আমি গিটকে কীভাবে বলতে পারি যে একটি নির্দিষ্ট ফাইলে সংঘাতের জন্য মার্জনীয়তার জন্য সর্বদা আমার স্থানীয় সংস্করণটি নির্বাচন করতে হয়?


101

বলুন আমি গিট সংগ্রহস্থলের মাধ্যমে কারও সাথে সহযোগিতা করছি, এবং একটি নির্দিষ্ট ফাইল রয়েছে যা আমি কখনই কোনও বাহ্যিক পরিবর্তন গ্রহণ করতে চাই না।

প্রতিবার যখন আমি টান পড়ি তখন দ্বিধাবিভক্ত একীকরণের বিষয়ে অভিযোগ না করার জন্য কী আমার স্থানীয় রেপো সেট আপ করার কোনও উপায় আছে? এই ফাইলটি মার্জ করার সময় আমি সর্বদা আমার স্থানীয় সংস্করণ নির্বাচন করতে চাই।


4
.Gitattributes এবং একটি খুব বেসিক "মার্জ ড্রাইভার" এর মাধ্যমে সবেমাত্র একটি সহজ সমাধান জুড়েছে
ভোনসি

12
টিডি; এলআর:echo 'path/to/file merge=ours' >> .gitattributes && git config --global merge.ours.driver true
সিরো সান্তিলি 郝海东 冠状 病 六四 事件

@ সিরোস্যান্টিলি: লিনাক্সে মনোযোগের মতো কাজ করে। এই ড্রাইভারটি
গিটে

আপনি কি নিজের পরিবর্তনগুলি ফাইলটিতে ঠেকাতে চান? অথবা এটি উদাহরণস্বরূপ এমন কোনও কনফিগার ফাইল যেখানে ডিফল্ট গিটে সঞ্চিত থাকে।
ইয়ান রিংরোজ

@ সিরোস্যান্টিলি comment 改造 中心 六四 事件 法轮功 法轮功 'র মন্তব্যটি সঠিক, তবে এটি আপনার সিস্টেমে প্রতিটি রেপোর সাথে --globalট্যাগ সহ এই আচরণটি ঘটায় । আপনি যদি কেবল একটি রেপোর জন্য এই আচরণটি করতে চান তবে --globalপতাকাটি ছেড়ে দিন :echo 'path/to/file merge=ours' >> .gitattributes && git config merge.ours.driver true
মেজরবোট

উত্তর:


140

একটি কনফিগার ফাইলের নির্দিষ্ট উদাহরণে আমি রনের উত্তরের সাথে একমত হব :
একটি কনফিগারেশন আপনার কর্মক্ষেত্রের "ব্যক্তিগত" হওয়া উচিত (সুতরাং "একটি .gitignoreফাইলের মধ্যে ঘোষিত" হিসাবে "উপেক্ষা করা ")।
এতে টোকেনাইজড মান সহ আপনার একটি কনফিগার ফাইল টেমপ্লেট থাকতে পারে এবং সেই ফাইলটিকে ব্যক্তিগত (এবং উপেক্ষা করা) কনফিগার ফাইলে রূপান্তরকারী একটি স্ক্রিপ্ট থাকতে পারে ।config.template


তবে, এই নির্দিষ্ট মন্তব্যটি আরও বেশি বিস্তৃত সাধারণ প্রশ্নের উত্তর দেয় না, যেমন আপনার প্রশ্ন (!):

আমি গিটকে কীভাবে বলি যে কোনও নির্দিষ্ট ফাইলে সংঘাতের সংশ্লেষের জন্য সর্বদা আমার স্থানীয় সংস্করণটি নির্বাচন করতে পারি? (যে কোনও ফাইল বা ফাইলের গ্রুপের জন্য)

এই জাতীয় মার্জটি একটি "অনুলিপি সংযুক্তি", যাতে আপনি যখনই কোনও বিরোধ হয় তখন সর্বদা একটি ফাইলের 'আমাদের' বা 'তাদের' সংস্করণটি অনুলিপি করবেন।

(যেমন ব্রায়ান Vandenberg নোট মন্তব্য , ' ours' এবং ' theirs' এখানে একটি একত্রীকরণ জন্য ব্যবহার করা হয়
তারা হয় বিপরীত একটি জন্য রি-বেসের ফলে : দেখুন " Why is the meaning of “ours” and “theirs” reversed with git-svn", যা একটি রি-বেসের ফলে ব্যবহার করে, " git rebase, সম্পর্কে অবগত থাকার 'স্থানীয়' এবং 'রিমোট' ' )

"একটি ফাইল" (সাধারণভাবে একটি ফাইল, "কনফিগারেশন" ফাইলের কথা বলছেন না, কারণ এটি একটি খারাপ উদাহরণ), আপনি এটি মার্জগুলির মাধ্যমে ডাকা একটি কাস্টম স্ক্রিপ্টের মাধ্যমে অর্জন করতে পারবেন would
গিট সেই স্ক্রিপ্টটিকে কল করবে কারণ আপনার কাছে গিটট্রিবিটস মান নির্ধারণ করা হবে যা একটি কাস্টম মার্জ ড্রাইভারকে সংজ্ঞায়িত করে ।

"কাস্টম মার্জ ড্রাইভার" এই ক্ষেত্রে, একটি খুব সাধারণ স্ক্রিপ্ট যা মূলত বর্তমান সংস্করণটি অপরিবর্তিত রাখবে, তাই আপনাকে সর্বদা আপনার স্থানীয় সংস্করণ নির্বাচন করতে দেয়।

আইই।, সিরো সান্টিলি দ্বারা উল্লিখিত :

echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true

আসুন পরীক্ষা করে দেখি যে একটি সাধারণ দৃশ্যে, উইন্ডোজে একটি এমএসসিগিট 1.6.3 সহ, কেবলমাত্র ডস সেশনে:

cd f:\prog\git\test
mkdir copyMerge\dirWithConflicts
mkdir copyMerge\dirWithCopyMerge
cd copyMerge
git init
Initialized empty Git repository in F:/prog/git/test/copyMerge/.git/

এখন, দুটি ফাইল তৈরি করুন, যার উভয়টির মধ্যে দ্বন্দ্ব থাকবে, তবে কোনটি আলাদাভাবে মার্জ হবে।

echo a > dirWithConflicts\a.txt
echo b > dirWithCopyMerge\b.txt
git add -A
git commit -m "first commit with 2 directories and 2 files"
[master (root-commit) 0adaf8e] first commit with 2 directories and 2 files

আমরা এই দুটি ফাইলের সামগ্রীতে দুটি ভিন্ন গিট শাখায় "বিরোধ" প্রবর্তন করব:

git checkout -b myBranch
Switched to a new branch 'myBranch'
echo myLineForA >> dirWithConflicts\a.txt
echo myLineForB >> dirWithCopyMerge\b.txt
git add -A
git commit -m "add modification in myBranch"
[myBranch 97eac61] add modification in myBranch

git checkout master
Switched to branch 'master'
git checkout -b hisBranch
Switched to a new branch 'hisBranch'
echo hisLineForA >> dirWithConflicts\a.txt
echo hisLineForB >> dirWithCopyMerge\b.txt
git add -A
git commit -m "add modification in hisBranch"
[hisBranch 658c31c] add modification in hisBranch

এখন, এর সাথে "মাই ব্রাঞ্চ" এর সাথে "তাঁর ব্রাঞ্চ" মার্জ করার চেষ্টা করা যাক:

  • বিরোধী মার্জগুলির জন্য ম্যানুয়াল রেজোলিউশন
  • ছাড়া জন্য dirWithCopyMerge\b.txtযেখানে আমি সব সময় রাখতে চান আমার সংস্করণ b.txt

যেহেতু মার্জটি ' MyBranch' এ দেখা যায় , তাই আমরা এটিতে আবার ফিরে যাব, এবং ' gitattributes' 'নির্দেশাবলী যুক্ত করব যা মার্জ আচরণটি কাস্টমাইজ করবে।

git checkout myBranch
Switched to branch 'myBranch'
echo b.txt merge=keepMine > dirWithCopyMerge\.gitattributes
git config merge.keepMine.name "always keep mine during merge"
git config merge.keepMine.driver "keepMine.sh %O %A %B"
git add -A
git commit -m "prepare myBranch with .gitattributes merge strategy"
[myBranch ec202aa] prepare myBranch with .gitattributes merge strategy

আমাদের ডিরেক্টরিতে .gitattributesসংজ্ঞায়িত একটি ফাইল রয়েছে dirWithCopyMerge(কেবলমাত্র সেই শাখায় সংজ্ঞায়িত হবে যেখানে মার্জটি ঘটবে myBranch:), এবং আমাদের একটি .git\configফাইল রয়েছে যা এখন মার্জ ড্রাইভার রয়েছে।

[merge "keepMine"]
        name = always keep mine during merge
        driver = keepMine.sh %O %A %B

আপনি যদি এখনও KeepMine.sh সংজ্ঞায়িত না করে এবং যাহাই হউক না কেন মার্জটি চালু করেন, আপনি যা পান তা এখানে।

git merge hisBranch
sh: keepMine.sh: command not found
fatal: Failed to execute internal merge
git st
# On branch myBranch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   dirWithConflicts/a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

type dirWithConflicts\a.txt
a
<<<<<<< HEAD:dirWithConflicts/a.txt
myLineForA
=======
hisLineForA
>>>>>>> hisBranch:dirWithConflicts/a.txt

ওটা দারুন:

  • a.txt একীভূত হতে প্রস্তুত এবং এতে বিরোধ রয়েছে
  • b.txtএখনও বিচ্ছিন্ন, যেহেতু মার্জ ড্রাইভারটি এটির যত্ন নেবে ( .gitattributesতার ডিরেক্টরিতে ফাইলটিতে নির্দেশের কারণে) to

keepMine.shআপনার %PATH%(অথবা $PATHআমাদের ইউনিক্স বন্ধুর জন্য যে কোনও জায়গায় সংজ্ঞা দিন) আমি অবশ্যই উভয়টিই করি: ভার্চুয়ালবক্স সেশনে আমার উবুন্টু সেশন রয়েছে

যেমন lrkwz দ্বারা মন্তব্য করা হয়েছে , এবং গিট - গিট বৈশিষ্ট্যগুলি অনুকূলিতকরণের " মার্জ কৌশল " বিভাগে বর্ণনা করা হয়েছে , আপনি শেল স্ক্রিপ্টটি শেল কমান্ডের সাথে প্রতিস্থাপন করতে পারেন ।true

git config merge.keepMine.driver true

তবে সাধারণ ক্ষেত্রে, আপনি একটি স্ক্রিপ্ট ফাইল সংজ্ঞায়িত করতে পারেন:

keepMine.sh

# I want to keep MY version when there is a conflict
# Nothing to do: %A (the second parameter) already contains my version
# Just indicate the merge has been successfully "resolved" with the exit status
exit 0

(যে এক সহজ একত্রীকরণ চালক ছিল;) (যে ক্ষেত্রে, ব্যবহারে এমনকি সহজ true)
(আপনি অন্য সংস্করণ চালিয়ে যেতে, শুধুমাত্র সামনে যোগ চেয়েছিলেন exit 0লাইন:
cp -f $3 $2
ব্যাস আপনি একত্রীকরণ চালক aways সংস্করণ অপরের থেকে আসছে রাখা হবে। শাখা, যে কোনও স্থানীয় পরিবর্তনকে উপেক্ষা করে)

এখন, শুরু থেকে মার্জটি আবার চেষ্টা করুন:

git reset --hard
HEAD is now at ec202aa prepare myBranch with .gitattributes merge strategy

git merge hisBranch
Auto-merging dirWithConflicts/a.txt
CONFLICT (content): Merge conflict in dirWithConflicts/a.txt
Auto-merging dirWithCopyMerge/b.txt
Automatic merge failed; fix conflicts and then commit the result.

মার্জ ব্যর্থ হয় ... কেবলমাত্র a.txt এর জন্য
A.txt সম্পাদনা করুন এবং 'hisBunch' থেকে লাইনটি ছেড়ে দিন, তারপরে:

git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version

আসুন পরীক্ষা করুন যে এই মার্জ চলাকালীন b.txt সংরক্ষণ করা হয়েছে

type dirWithCopyMerge\b.txt
b
myLineForB

শেষ প্রতিশ্রুতি সম্পূর্ণ মার্জ প্রতিনিধিত্ব করে :

git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.

(মার্জ দিয়ে শুরু হওয়া লাইনটি এটি প্রমাণ করে)


গিট যেমন করবে তেমন আপনি মার্জ ড্রাইভারকে সংজ্ঞায়িত করতে, একত্রিত করতে এবং / অথবা ওভাররাইট করতে পারেন তা বিবেচনা করুন:

  • পরীক্ষা করুন <dir>/.gitattributes(যা প্রশ্নের দিকের একই ডিরেক্টরিতে রয়েছে): .gitattributesডিরেক্টরিতে অন্যটির উপর বিজয়ী হবে
  • তারপরে এটি পরীক্ষা করে .gitattributes(যা মূল ডিরেক্টরিতে রয়েছে), ইতিমধ্যে সেট না থাকলে কেবল নির্দেশিকা সেট করবে
  • অবশেষে এটি পরীক্ষা করে $GIT_DIR/info/attributes। এই ফাইলটি ইন-ট্রি সেটিংগুলিকে ওভাররাইড করতে ব্যবহৃত হয়। এটি <dir>/.gitattributesনির্দেশকে ওভাররাইট করবে ।

"সম্মিলন" দ্বারা, আমি "একত্রিত" একাধিক মার্জ ড্রাইভার।
নিক গ্রিন মন্তব্যগুলিতে প্রকৃতপক্ষে মার্জ চালকদের একত্রিত করার চেষ্টা করেছেন : " পাইথন গিট ড্রাইভারের মাধ্যমে পোমগুলি মার্জ করুন " দেখুন।
তবে, তাঁর অন্যান্য প্রশ্নে যেমন উল্লেখ করা হয়েছে , এটি কেবল দ্বন্দ্বের ক্ষেত্রে কাজ করে (উভয় শাখায় একযোগে পরিবর্তন)।


4
বিস্তারিত উত্তরের জন্য আপনাকে ধন্যবাদ! আমি বুঝতে পারি যে এটি সংস্করণ-নিয়ন্ত্রণের কনফিগার ফাইলগুলিতে কোনও ধারণা রাখে না, তবে আমি একটি সোজাসাপ্টা প্রেরণাদায়ী উদাহরণ অনুসরণ করেছি। আসলে, এটি আমার আগ্রহী যে বিস্তৃত প্রশ্ন। আমি আগে কখনও গিট মার্জ ড্রাইভারদের কথা শুনিনি, তাই আমাকে আলোকিত করার জন্য আপনাকে ধন্যবাদ।
saffsd

6
cp -f $3 $2সম্ভবত উদ্ধৃত করা উচিত, অর্থাত cp -f "$3" "$2"
আর্ক

4
@ ভনসি বিস্তারিত উত্তরের জন্য ধন্যবাদ! আমার এটির সমস্যাটি হ'ল এটি লোকেরা তাদের .git / কনফিগারেশনে ড্রাইভার সেট করার উপর নির্ভর করে। আমি নিজেই এই প্রকল্পে ড্রাইভারের তথ্য যুক্ত করতে চাই, সুতরাং এটি স্বয়ংক্রিয় এবং কম সেটআপের কাজ হবে। কোন পয়েন্টার?
জুয়ান দেলগাদো

4
@ulmangt: আপনি সেই স্ক্রিপ্টটি গিট রেপোতেও খুব বেশি সঞ্চয় করতে পারবেন, ... যতক্ষণ আপনি তার মূল ডিরেক্টরিটি PATH(ইউনিক্স বা উইন্ডোজ PATH) এ যুক্ত করার উপায় খুঁজে পান । যেহেতু সেই স্ক্রিপ্টটি ইউনিক্স ব্যাশ শেলের মাধ্যমে ব্যাখ্যা করা হবে বা মিংউইন ব্যাশ এমসিসজিট উইন্ডোজ শেলের মাধ্যমে, এটি বহনযোগ্য হবে।
ভনসি

5
@ ভনসি ধন্যবাদ আরও একটি ইস্যু। নির্দিষ্ট পরিস্থিতিতে (যদি স্থানীয় শাখায় একীভূত হওয়ার কোনও পরিবর্তন না ঘটে) এটি প্রদর্শিত হয় যে মার্জ ড্রাইভারটি কখনও কল করা হয় না, যার ফলস্বরূপ স্থানীয় ফাইলগুলি সংশোধিত হয় (যা কাস্টম মার্জ ড্রাইভার ব্যবহার করে বলে মনে করা হয়) মার্জ করার সময় তাদের পরিবর্তন থেকে রোধ করতে)। গিটকে সর্বদা মার্জ ড্রাইভার ব্যবহার করতে বাধ্য করার কোনও উপায় আছে কি ?
ulmangt

1

@ Ciro-santilli যেমন মন্তব্য করেছে, .gitattributesসেটিংস ব্যবহার করে এটি করার সহজ উপায় :

path/to/file merge=ours

এবং এই কৌশলটি এর সাথে সক্ষম করুন:

git config --global merge.ours.driver true

(আমি এটিকে আরও দৃশ্যমান করার জন্য উত্তর হিসাবে যুক্ত করছি তবে এটির জন্য নিজের ব্যবহারকারীর ক্রেডিটকে উপরে পাওয়ার চেষ্টা না করার জন্য এটি একটি সম্প্রদায় উইকি করে তুলছি Please দয়া করে এখানে তাকে প্রশ্ন দেওয়ার জন্য প্রশ্নটির অধীনে তার মন্তব্যটি উত্সাহিত করুন!)


(একদিকে: যদি কেউ মন্তব্য হিসাবে উত্তর দেয় এবং উত্তর যোগ না করে তবে একটি সি-ডাব্লু উত্তর লিখতে এবং ক্রেডিটগুলি গ্রহণ করা পুরোপুরি ঠিক they তারা যদি এখনও সক্রিয় সদস্য হয় তবে আপনি উত্তর যুক্ত করার জন্য তাদের পিং করতে পারেন যদি আপনি ইচ্ছুক, তবে তারা প্রযুক্তিগতভাবে ইতিমধ্যে তাদের সুযোগ ছিল :-))।
21

0

আমাদের একাধিক কনফিগার ফাইল রয়েছে যা আমরা কখনই ওভাররাইট করতে চাই না। তবে .gitignore এবং .gitattributes আমাদের পরিস্থিতিতে কাজ করে নি। আমাদের সমাধানটি ছিল কনফিগার্স শাখায় কনফিগার করা ফাইলগুলি সংরক্ষণ করা। তারপরে, গিট মার্জ করার সময় ফাইলগুলি পরিবর্তন করার অনুমতি দিন, তবে সংযুক্তির সাথে সাথেই "গিট চেকআউট শাখা -" ব্যবহার করুন। প্রতি সংযুক্তির পরে কনফিগার্স শাখা থেকে আমাদের কনফিগার ফাইলগুলি অনুলিপি করতে। বিশদ স্ট্যাকওভারফ্লো উত্তর এখানে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.