git - কোন ক্ষেত্রে 'গিট টান' ক্ষতিকারক হতে পারে?




git-pull (3)

আমার একজন সহকর্মী আছে যে দাবি করে যে git pull ক্ষতিকারক, এবং কেউ যখন এটি ব্যবহার করে তখন বিরক্ত হয়।

git pull কমান্ড আপনার স্থানীয় সংগ্রহস্থল আপডেট করতে ক্যানোনিকাল উপায় বলে মনে হচ্ছে। git pull ব্যবহার করে সমস্যা তৈরি করে? এটা কি সমস্যা সৃষ্টি করে? একটি গিট রিপোজিটরি আপডেট করার জন্য একটি ভাল উপায় আছে কি?


সারাংশ

ডিফল্টরূপে, git pull কোড মার্জটিতে শব্দ এবং জটিলতা যুক্ত করে যা একত্রিত করে git pull । উপরন্তু, pull আপনার পরিবর্তনগুলি কীভাবে ইনকামিং পরিবর্তনের দ্বারা প্রভাবিত হতে পারে সে সম্পর্কে চিন্তা করা সহজ করে তোলে।

git pull কমান্ডটি এতক্ষণ নিরাপদ যেহেতু এটি কেবল ফাস্ট-ফরওয়ার্ড মার্জ সঞ্চালন করে। যদি git pull কেবল দ্রুত-ফরোয়ার্ড মার্জ করতে কনফিগার করা হয় এবং কোন দ্রুত-ফরোয়ার্ড মার্জ সম্ভব না হয় তবে Git একটি ত্রুটির সাথে প্রস্থান করবে। এটি আপনাকে ইনকামিং কমিটিগুলি অধ্যয়ন করার সুযোগ দেবে, তারা কীভাবে আপনার স্থানীয় কমিটির উপর প্রভাব ফেলতে পারে এবং কর্মের সর্বোত্তম পদ্ধতি (মার্জ, রিবেস, রিসেট, ইত্যাদি) সিদ্ধান্ত নিতে পারে সে সম্পর্কে চিন্তা করে।

Git 2.0 এবং নতুনের সাথে, আপনি চালাতে পারেন:

git config --global pull.ff only

ডিফল্ট আচরণ শুধুমাত্র দ্রুত এগিয়ে পরিবর্তন করতে। 1.6.6 এবং 1.9.x এর মধ্যে গিট সংস্করণগুলির সাথে আপনাকে টাইপ করার অভ্যাস পেতে হবে:

git pull --ff-only

যাইহোক, গিট এর সব সংস্করণের সাথে, আমি এই মত একটি git up কনফিগার করার সুপারিশ:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

এবং git pull পরিবর্তে git up ব্যবহার করে। আমি git pull --ff-only উপর git pull --ff-only এই উপনাম পছন্দ git pull --ff-only কারণ:

  • এটি গিটের সমস্ত (অ-প্রাচীন) সংস্করণগুলির সাথে কাজ করে,
  • এটি সমস্ত আপস্ট্রিম শাখাগুলি (শুধুমাত্র আপনি যে শাখায় কাজ করছেন তা নয়) এবং
  • এটি পুরাতন origin/* শাখাগুলিকে সাফ করে যা আর প্রবাহের অস্তিত্ব নেই।

git pull সঙ্গে সমস্যা

এটি সঠিকভাবে ব্যবহার করা হয়, তাহলে git pull খারাপ না। গিটে সাম্প্রতিক পরিবর্তনগুলি সহজেই git pull ব্যবহার করা সহজ করেছে, তবে দুর্ভাগ্যবশত একটি প্লেইন git pull ডিফল্ট আচরণে বেশ কিছু সমস্যা রয়েছে:

  • এটা ইতিহাসে অপ্রয়োজনীয় nonlinearities প্রবর্তন
  • এটা ইচ্ছাকৃতভাবে আপস্ট্রিম আউট rebased ছিল যে commits reintroduce সহজ করে তোলে
  • এটি অনির্দেশ্য উপায়ে আপনার কাজ ডিরেক্টরি সংশোধন করে
  • অন্য কারোর কাজ পর্যালোচনা করার জন্য আপনি যা করছেন তা বিরাম git pull
  • এটি দূরবর্তী শাখায় সঠিকভাবে রিবেস করা কঠিন করে তোলে
  • এটি রিমোট রেপোতে মুছে ফেলা শাখাগুলি পরিষ্কার করে না

এই সমস্যা নীচে আরো বিস্তারিত বর্ণিত হয়।

Nonlinear ইতিহাস

ডিফল্টরূপে, git pull কমান্ডটি git merge @{u} দ্বারা চলমান git fetch সমতুল্য। যদি স্থানীয় রিপোজিটরিতে অপ্রচলিত কাজ থাকে তবে git pull মার্জ অংশটি একটি মার্জ কমিট তৈরি করে।

কৃত্রিমভাবে বিযুক্তির বিষয়ে কিছুই খারাপ নেই, তবে তারা বিপজ্জনক হতে পারে এবং সম্মানের সাথে আচরণ করা উচিত:

  • কমিট মার্জ পরীক্ষা নিরীক্ষা কঠিন। একটি মার্জ কি করছেন তা বোঝার জন্য, আপনাকে সমস্ত পিতামাতার মধ্যে পার্থক্য বুঝতে হবে। একটি প্রচলিত বিভাজন ভাল এই বহু-মাত্রিক তথ্য প্রকাশ করে না। বিপরীতে, স্বাভাবিক কাজগুলির একটি সিরিজ পর্যালোচনা করা সহজ।
  • দ্বন্দ্ব রেজল্যুশন মার্জ করুন চতুর, এবং ভুলগুলি প্রায়ই দীর্ঘ সময়ের জন্য অবহেলা করা হয় কারণ সম্মতিগুলি পর্যালোচনা করা কঠিন।
  • মার্জ শান্তভাবে নিয়মিত commits প্রভাব supersede করতে পারেন। কোড আর ক্রমবর্ধমান commits যোগফল হয়, আসলে কি পরিবর্তন সম্পর্কে ভুল বোঝাবুঝি নেতৃস্থানীয়।
  • বিভাজন একত্রিত করা কিছু ক্রমাগত ইন্টিগ্রেশন স্কিমগুলি বিঘ্নিত করতে পারে (উদাহরণস্বরূপ, দ্বিতীয় অভিভাবক অগ্রগতিতে অসম্পূর্ণ কাজ নির্দেশ করে যে অভিযুক্ত কনভেনশনের অধীনে শুধুমাত্র প্রথম অভিভাবক পথটি স্বয়ংক্রিয়ভাবে তৈরি করুন)।

অবশ্যই একটি সময় এবং একত্রীকরণের জন্য একটি জায়গা আছে, কিন্তু যখন মেশানো উচিত এবং ব্যবহার করা উচিত নয় তখন বোঝার আপনার সংগ্রহস্থলের ব্যবহারযোগ্যতা উন্নত করতে পারে।

উল্লেখ্য, গিটের উদ্দেশ্যটি সহজেই ভাগ করে নেওয়ার মতো ইতিহাসের সঠিকভাবে রেকর্ড না করার জন্য কোডব্রেসের বিবর্তনকে ভাগ করা এবং এটি ব্যবহার করা সহজ। (যদি আপনি ভিন্নমত পোষণ করেন তবে rebase কমান্ডটিকে কেন এবং কেন এটি তৈরি করা হয়েছিল তা বিবেচনা করুন।) git pull দ্বারা তৈরি মার্জ git pull অন্যদের কাছে কার্যকর শব্দার্থবিদ্যা প্রকাশ করে না-তারা কেবল বলে যে অন্য কেউ আপনার পরিবর্তনগুলির সাথে সম্পন্ন হওয়ার আগে সংগ্রহস্থলের দিকে ধাক্কা দেয়। । কেন তারা অন্যের কাছে অর্থপূর্ণ না হলে বিপদজনক হতে পারে এবং বিপজ্জনক হতে পারে?

একত্রিত হওয়ার পরিবর্তে রিসেজে git pull কনফিগার করা সম্ভব, তবে এতে সমস্যা রয়েছে (পরে আলোচনা করা হয়েছে)। পরিবর্তে, git pull শুধুমাত্র দ্রুত এগিয়ে মার্জ করতে কনফিগার করা উচিত।

Rebased আউট কমিটির পুনঃপ্রবর্তন

ধরুন কেউ কেউ একটি শাখা রিবাউস এবং বল এটি pushs। এটি সাধারণত ঘটতে পারে না, তবে এটি কখনও কখনও প্রয়োজনীয় (উদাহরণস্বরূপ, একটি 50 জিআইবি লগ ফাইল মুছে ফেলার জন্য যা দুর্ঘটনাক্রমে ধাক্কা এবং ধাক্কা দেয়)। git pull দ্বারা সম্পন্ন মার্জ আপস্ট্রিম শাখার নতুন সংস্করণটিকে পুরানো সংস্করণে মার্জ করবে যা এখনও আপনার স্থানীয় সংগ্রহস্থলে উপস্থিত রয়েছে। আপনি ফলাফল ধাক্কা, পিচ কাঁটাচামচ এবং টর্চ আপনার পথে আসার শুরু হবে।

কিছু বাস্তব সমস্যা বলার অপেক্ষা রাখে না যে যুক্তি হতে পারে। হ্যাঁ, সাধারনত যখনই সম্ভব হয় তখন বল প্রয়োগ করা এড়িয়ে চলতে পরামর্শ দেওয়া হয় তবে কখনও কখনও এটি অযৌক্তিক হয়। বিকাশকারীদের অবশ্যই আপডেটগুলির সাথে মোকাবিলা করার জন্য প্রস্তুত থাকতে হবে, কারণ তারা কখনও কখনও ঘটবে। এই git pull একটি সাধারণ git pull মাধ্যমে পুরানো commits মধ্যে মার্জ না মানে।

অবাক কাজ ওয়ার্কিং পরিবর্তন

git pull সম্পন্ন না হওয়া পর্যন্ত কাজ নির্দেশিকা বা সূচী দেখতে কেমন হবে তা পূর্বাভাস করার কোন উপায় নেই। আপনি অন্য কিছু করতে পারার আগে এটি সমাধান করতে হবে এমন একত্রিত দ্বন্দ্ব থাকতে পারে, এটি আপনার কাজের নির্দেশিকাতে 50 জিআইবি লগ ফাইল উপস্থাপন করতে পারে কারণ এটি দুর্ঘটনাক্রমে এটির দিকে ঠেলে দেয়, এটি এমন একটি ডিরেক্টরিটির নামকরণ করতে পারে যা আপনি কাজ করছেন ইত্যাদি।

git remote update -p (বা git fetch --all -p ) আপনি একত্রিত বা পুনঃবিবেচনার সিদ্ধান্ত নেওয়ার আগে অন্য লোকেদের কৃতিত্বগুলি দেখতে পারবেন, যা আপনাকে পদক্ষেপ নেওয়ার আগে একটি পরিকল্পনা তৈরি করার অনুমতি দেয়।

অন্যান্য মানুষের Commits পর্যালোচনা অসুবিধা

ধরুন আপনি কিছু পরিবর্তন করার মাঝখানে আছেন এবং কেউ কেউ আপনাকে কিছু ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধ git pull মার্জ (বা রিবেস) ক্রিয়াকলাপটি কাজ ডিরেক্টরি এবং সূচীকে সংশোধন করে, যার অর্থ আপনার কার্য নির্দেশক এবং সূচী অবশ্যই পরিষ্কার হওয়া উচিত।

আপনি git stash ব্যবহার করতে পারেন এবং তারপরে git pull তবে আপনি পর্যালোচনার শেষ হলে কী করবেন? আপনি যেখানে ছিল ফিরে পেতে আপনি git pull দ্বারা নির্মিত মার্জ পূর্বাবস্থায় ফেরাতে হবে এবং স্ট্যাশ প্রয়োগ।

git remote update -p (বা git fetch --all -p ) কাজ ডিরেক্টরি বা সূচী সংশোধন করে না, সুতরাং আপনি যে কোনও সময়ে চালানো নিরাপদ-এমনকি যদি আপনি স্টেজ এবং / অথবা অস্থায়ী পরিবর্তনগুলিও করেন। আপনি যা করছেন তা আপনি থামাতে পারেন এবং আপনি যে কাজটি করছেন তার স্ট্যাশিং বা সমাপ্তির বিষয়ে উদ্বেগ ছাড়াই অন্য কারোর কমিটির পর্যালোচনা করুন। git pull আপনি যে নমনীয়তা দেয় না।

একটি রিমোট শাখা সম্মুখের রিবাজ

একটি সাধারণ গিট ব্যবহার প্যাটার্নটি জিট git pull চালু করে মার্জ git pull করতে git rebase @{u} একটি git rebase @{u} দ্বারা অনুসরণ করা সর্বশেষ পরিবর্তন আনতে একটি git pull করতে হয়। এটি সাধারণ যে গিটের এই branch.autosetuprebase branch.<branch>.rebase সম্পাদন করার জন্য এই দুটি পদক্ষেপকে এক ধাপে হ্রাস করার জন্য কিছু কনফিগারেশন বিকল্প রয়েছে branch.<branch>.rebase ( branch.<branch>.rebase , branch.autosetuprebase এবং pull.rebase বিকল্পগুলি দেখুন )।

দুর্ভাগ্যবশত, যদি আপনার কোনও সুরক্ষিত মার্জ কমিট থাকে যা আপনি সংরক্ষণ করতে চান (উদাহরণস্বরূপ, একটি ধাক্কাযুক্ত বৈশিষ্ট্য শাখাটি master মধ্যে মার্জ করা একটি কমিট), কোনও রিবেস-পুল ( branch.<branch>.rebase সাথে git pull branch.<branch>.rebase true সেট) একত্রীকরণ দ্বারা অনুসরণ একত্রিত করা (ডিফল্ট git pull আচরণ) কাজ করবে। --preserve-merges (এটি ডিএজি --preserve-merges ) ছাড়াই --preserve-merges বিকল্প ছাড়া। রিবেস-পুল অপারেশনটি মার্জগুলি সংরক্ষণের জন্য কনফিগার করা যাবে না এবং একটি মিট- git rebase -p @{u} অনুসরণ করে একটি git rebase -p @{u} মার্জ-পুল দ্বারা সৃষ্ট git rebase -p @{u} না। আপডেট: গিট v1.8.5 যোগ git pull --rebase=preserve এবং git config pull.rebase preserve । এই কারণে git rebase --preserve-merges আপস্ট্রীম git rebase --preserve-merges আনতে পরে। (হেড আপ জন্য funkaster ধন্যবাদ!)

মুছে ফেলা শাখা পরিষ্কার আপ

git pull দূরবর্তী সংগ্রহস্থল থেকে মুছে ফেলা হয়েছে যে শাখার অনুরূপ দূরবর্তী ট্র্যাকিং শাখা ছিঁড়ে না। উদাহরণস্বরূপ, যদি কেউ রিমোট রেপো থেকে শাখা foo মুছে ফেলে তবে আপনি এখনও origin/foo দেখতে পাবেন।

এটি ব্যবহারকারীদের দুর্ঘটনাক্রমে নিহত শাখার পুনরুজ্জীবিত করে তোলে কারণ তারা মনে করে যে তারা এখনও সক্রিয়।

একটি ভাল বিকল্প: git pull পরিবর্তে git up ব্যবহার করুন

পরিবর্তে git pull , আমি তৈরি এবং নিম্নলিখিত git up উপনাম ব্যবহার করে সুপারিশ:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

এই উপনাম সব আপস্ট্রিম শাখার (মৃত শাখার ছাঁটাই) থেকে সর্বশেষ সমস্ত কাজ ডাউনলোড করে এবং স্থানীয় শাখাটি দ্রুত প্রবাহকে আপস্ট্রিম শাখায় সর্বশেষ কমিটিতে পাঠানোর চেষ্টা করে। সফল হলে, কোন স্থানীয় কমিটি ছিল না, তাই দ্বন্দ্ব মার্জ করার কোন ঝুঁকি ছিল না। স্থানীয় (অপস্পেড) সংঘটিত হলে দ্রুত ফরোয়ার্ড ব্যর্থ হবে, এটি আপনাকে পদক্ষেপ নেওয়ার আগে আপস্ট্রিম কমিটির পর্যালোচনা করার সুযোগ দেবে।

এটি এখনও আপনার কার্যক্ষেত্রকে অনির্দেশ্য উপায়ে সংশোধন করে, তবে শুধুমাত্র যদি আপনার কোন স্থানীয় পরিবর্তন না থাকে। git pull , git up আপনি একটি বিভাজক সংঘাত ঠিক করার জন্য প্রত্যাশা একটি প্রম্পট আপনি ড্রপ করবে না।

আরেকটি বিকল্প: git pull --ff-only --all -p

নিম্নলিখিত উপরের git up উপনাম একটি বিকল্প:

git config --global alias.up 'pull --ff-only --all -p'

git up এই সংস্করণ আগের git up হিসাবে একই আচরণ আছে, ব্যতীত:

  • আপনার স্থানীয় শাখাটি আপস্ট্রিম শাখার সাথে কনফিগার করা না থাকলে ত্রুটির বার্তাটি আরও বেশি রহস্যজনক
  • এটি একটি অননুমোদিত বৈশিষ্ট্য (দ্য- -p আর্গুমেন্ট, যা fetch প্রেরণ করা হয়) উপর নির্ভর করে যা গিটের ভবিষ্যতের সংস্করণগুলিতে পরিবর্তন হতে পারে

আপনি Git 2.0 বা নতুন চলমান হয়

Git 2.0 এবং নতুনের সাথে আপনি ডিফল্টভাবে ফাস্ট-ফরওয়ার্ড মার্জ করতে শুধুমাত্র git pull কনফিগার করতে পারেন:

git config --global pull.ff only

এটি git pull git pull --ff-only মত কাজ করার জন্য git pull দেয়, তবে এটি এখনও সব আপস্ট্রিমটি গ্রহণ করে না বা পুরাতন origin/* শাখাগুলিকে সাফ করে না, তাই আমি এখনও git up পছন্দ করি।


আপনি সঠিকভাবে Git ব্যবহার করা হয় তাহলে এটি ক্ষতিকারক বিবেচিত হয় না। আমি দেখি এটি আপনার ব্যবহার ক্ষেত্রে নেতিবাচকভাবে কীভাবে প্রভাবিত করে, তবে ভাগ করা ইতিহাস পরিবর্তন না করেই আপনি কেবল সমস্যাগুলি এড়াতে পারেন।


গ্রহণযোগ্য উত্তর দাবি

রিবেস-পুল অপারেশন মার্জ সংরক্ষণ করতে কনফিগার করা যাবে না

কিন্তু গিট 1.8.5 হিসাবে, যে উত্তর পোস্ট করে, আপনি করতে পারেন

git pull --rebase=preserve

অথবা

git config --global pull.rebase preserve

অথবা

git config branch.<name>.rebase preserve

docs বলেছেন

যখন preserve, তখনও 'গিট --preserve-merges ' বরাবর --preserve-merges পাস করে যাতে স্থানীয়ভাবে একত্রিত করা হয় 'গিট পুল' চালানোর মাধ্যমে।

এই পূর্ববর্তী আলোচনার আরো বিস্তারিত তথ্য এবং চিত্রাবলী আছে : গিট পুল --rebase - preserve-merges । এটি ব্যাখ্যা করে কেন git pull --rebase=preserve git pull --rebase --preserve-merges হিসাবে একই নয়, যা সঠিক জিনিসটি না করে।

এই অন্যান্য পূর্ববর্তী আলোচনাটি কীভাবে রিবেজের সংরক্ষণ-বিভাজক রূপটি আসলে কী করে এবং নিয়মিত বিনিময়ের চেয়ে এটি আরও বেশি জটিল কীভাবে ব্যাখ্যা করে: Git এর "পুনঃপ্রতিষ্ঠিত - সুরক্ষিত-মার্জ" কী করে (এবং কেন?) ঠিক কী করে?





git-pull