Đối với trường hợp cụ thể của tệp cấu hình, tôi đồng ý với câu trả lời của Ron :
cấu hình phải là "riêng tư" đối với không gian làm việc của bạn (do đó "bị bỏ qua", như trong "được khai báo trong .gitignore
tệp").
Bạn có thể có một mẫu tệp cấu hình với các giá trị được mã hóa trong đó và một tập lệnh chuyển đổi config.template
tệp đó thành tệp cấu hình riêng tư (và bị bỏ qua).
Tuy nhiên, nhận xét cụ thể đó không trả lời câu hỏi rộng hơn, tổng quát hơn, tức là câu hỏi của bạn (!):
Làm cách nào để yêu cầu git luôn chọn phiên bản cục bộ của tôi cho các hợp nhất bị xung đột trên một tệp cụ thể? (đối với bất kỳ tệp hoặc nhóm tệp nào)
Loại hợp nhất này là "hợp nhất sao chép", trong đó bạn sẽ luôn sao chép phiên bản 'của chúng tôi' hoặc 'của họ' bất cứ khi nào có xung đột.
(như Brian Vandenberg lưu ý trong các nhận xét , ' ours
' và ' theirs
' ở đây được sử dụng để hợp nhất .
Chúng được đảo ngược cho một rebase : see " Why is the meaning of “ours” and “theirs” reversed with git-svn
", sử dụng một rebase " git rebase
, theo dõi 'local' và 'remote' " )
Đối với "một tệp" (một tệp nói chung, không nói đến tệp "cấu hình", vì nó là một ví dụ xấu), bạn sẽ đạt được điều đó với một tập lệnh tùy chỉnh được gọi thông qua hợp nhất.
Git sẽ gọi tập lệnh đó vì bạn sẽ xác định giá trị gitattributes , giá trị này xác định trình điều khiển hợp nhất tùy chỉnh .
Trong trường hợp này, "trình điều khiển hợp nhất tùy chỉnh" là một tập lệnh rất đơn giản về cơ bản sẽ không thay đổi phiên bản hiện tại, do đó cho phép bạn luôn chọn phiên bản cục bộ của mình.
IE., Theo ghi nhận của Ciro Santilli :
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
Hãy kiểm tra điều đó trong một kịch bản đơn giản, với msysgit 1.6.3 trên Windows, chỉ trong một phiên DOS:
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/
Bây giờ, hãy tạo hai tệp, cả hai sẽ có xung đột, nhưng sẽ được hợp nhất khác nhau.
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
Chúng tôi sẽ giới thiệu một "xung đột" trong nội dung của cả hai tệp đó trong hai nhánh git khác nhau:
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
Bây giờ, hãy thử hợp nhất "hisBranch" với "myBranch", với:
- giải quyết thủ công cho các hợp nhất xung đột
- ngoại trừ cho
dirWithCopyMerge\b.txt
nơi tôi luôn muốn giữ tôi phiên bản của b.txt
.
Vì quá trình hợp nhất xảy ra trong ' MyBranch
', chúng tôi sẽ chuyển về nó và thêm các lệnh ' gitattributes
' sẽ tùy chỉnh hành vi hợp nhất.
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
Chúng tôi có một .gitattributes
tệp được xác định trong dirWithCopyMerge
thư mục (chỉ được xác định trong nhánh nơi hợp nhất sẽ xảy ra myBranch
:), và chúng tôi có một .git\config
tệp hiện chứa trình điều khiển hợp nhất.
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B
Nếu bạn chưa xác định keepMine.sh và vẫn khởi chạy hợp nhất, đây là những gì bạn nhận được.
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
Điều đó là tốt:
a.txt
sẵn sàng được hợp nhất và có xung đột trong đó
b.txt
vẫn chưa bị ảnh hưởng, vì trình điều khiển hợp nhất phải xử lý nó (do chỉ thị trong .gitattributes
tệp trong thư mục của nó).
Xác định một keepMine.sh
bất kỳ nơi nào trong của bạn %PATH%
(hoặc $PATH
cho người bạn Unix của chúng tôi. Tất nhiên tôi làm cả hai: Tôi có phiên Ubuntu trong phiên VirtualBox)
Như nhận xét của lrkwz và được mô tả trong phần " Chiến lược hợp nhất " của Tùy chỉnh Git - Thuộc tính Git , bạn có thể thay thế shell script bằng lệnh shell true
.
git config merge.keepMine.driver true
Nhưng trong trường hợp chung, bạn có thể xác định một tệp script:
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
(đó là một tài xế hợp nhất đơn giản;) (Thậm chí đơn giản trong trường hợp đó, việc sử dụng true
)
(Nếu bạn muốn giữ phiên bản khác, chỉ cần thêm trước khi exit 0
dòng:
cp -f $3 $2
.
Vậy là xong Bạn nhập tài xế aways sẽ giữ phiên bản đến từ bên kia. nhánh, ghi đè mọi thay đổi cục bộ)
Bây giờ, hãy thử lại hợp nhất từ đầu:
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.
Hợp nhất không thành công ... chỉ cho a.txt .
Chỉnh sửa a.txt và để dòng từ 'hisBranch', sau đó:
git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version
Hãy kiểm tra xem b.txt đã được giữ nguyên trong quá trình hợp nhất này chưa
type dirWithCopyMerge\b.txt
b
myLineForB
Cam kết cuối cùng đại diện cho sự hợp nhất đầy đủ :
git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.
(Dòng bắt đầu bằng Merge chứng tỏ điều đó)
Hãy xem xét bạn có thể xác định, kết hợp và / hoặc ghi đè trình điều khiển hợp nhất, vì Git sẽ:
- kiểm tra
<dir>/.gitattributes
(nằm trong cùng thư mục với đường dẫn được đề cập): sẽ chiếm ưu thế so với đường dẫn khác .gitattributes
trong thư mục
- Sau đó, nó kiểm tra
.gitattributes
(nằm trong thư mục mẹ), sẽ chỉ thiết lập các chỉ thị nếu chưa được thiết lập
- Cuối cùng nó kiểm tra
$GIT_DIR/info/attributes
. Tệp này được sử dụng để ghi đè cài đặt trong cây. Nó sẽ ghi đè các <dir>/.gitattributes
chỉ thị.
Bằng cách "kết hợp", ý tôi là "tổng hợp" nhiều trình điều khiển hợp nhất.
Nick Green cố gắng, trong các ý kiến , để thực sự kết hợp trình điều khiển hợp nhất: xem " qua python git lái xe Merge pom của ".
Tuy nhiên, như đã đề cập trong câu hỏi khác của anh ấy , nó chỉ hoạt động trong trường hợp xung đột (sửa đổi đồng thời ở cả hai nhánh).