Tôi đang hợp nhất trong một chi nhánh xa có thể có nhiều xung đột. Làm thế nào tôi có thể biết nếu nó sẽ có xung đột hay không?
Tôi không thấy bất cứ điều gì như --dry-run
trên git-merge
.
Tôi đang hợp nhất trong một chi nhánh xa có thể có nhiều xung đột. Làm thế nào tôi có thể biết nếu nó sẽ có xung đột hay không?
Tôi không thấy bất cứ điều gì như --dry-run
trên git-merge
.
Câu trả lời:
Như đã lưu ý trước đó, vượt qua trong --no-commit
cờ, nhưng để tránh cam kết chuyển tiếp nhanh, cũng chuyển qua --no-ff
, như vậy:
$ git merge --no-commit --no-ff $BRANCH
Để kiểm tra các thay đổi theo giai đoạn:
$ git diff --cached
Và bạn có thể hoàn tác hợp nhất, ngay cả khi đó là hợp nhất chuyển tiếp nhanh:
$ git merge --abort
git merge --only-if-there-wont-be-any-conflicts
hoặc git diff --show-conflicts <commit>
sẽ thực sự tiện dụng. Xấu hổ là không thể, hoặc tôi đang thiếu một cái gì đó?
git pull --ff-only
!
Tôi chỉ phải thực hiện một phương thức tự động tìm thấy xung đột giữa kho lưu trữ và điều khiển từ xa. Giải pháp này thực hiện hợp nhất trong bộ nhớ để nó không chạm vào chỉ mục, cũng như cây làm việc. Tôi nghĩ rằng đây là cách an toàn nhất có thể bạn có thể giải quyết vấn đề này. Đây là cách nó hoạt động:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
( mergebase là id thập lục phân mà cơ sở hợp nhất được in ở bước trước)Bây giờ giả sử rằng bạn muốn hợp nhất chủ từ xa với chủ địa phương, nhưng bạn có thể sử dụng bất kỳ nhánh nào. git merge-tree
sẽ thực hiện hợp nhất trong bộ nhớ và in kết quả ra đầu ra tiêu chuẩn. Grep cho các mẫu <<
hoặc >>
. Hoặc bạn có thể in đầu ra ra một tệp và kiểm tra xem. Nếu bạn tìm thấy một dòng bắt đầu bằng 'thay đổi trong cả hai' thì rất có thể sẽ có xung đột.
git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"
Đơn giản là tuyệt vời! +100
+<<<<<<< .our
vì vậy tôi sử dụng một biểu thức grep nhưgrep -q '^+<* \.our$'
Giải pháp vũ phu đơn giản của tôi cho việc này là:
Tạo một nhánh "tiền chính" (từ khóa học chính)
Hợp nhất tất cả những điều bạn muốn vào pre-master này.
Sau đó, bạn có thể thấy cách hợp nhất đã xảy ra mà không cần chạm vào chủ.
Dù sao, tôi sẽ làm theo lời khuyên của @ cam80.
git merge --abort
nếu có xung đột, git reset --hard HEAD~1
nếu có hợp nhất hoặc git reset --hard origin/master
. Tạo một nhánh khác mang lại cho bạn cảm giác an toàn nhưng nếu bạn học cách git hoạt động, bạn sẽ hiểu đó là nỗi sợ bị đặt nhầm chỗ. Khi mối quan tâm là về việc không thay đổi bản sao làm việc, điều này không cung cấp giải pháp.
git merge --no-commit
sẽ không hủy bỏ hợp nhất nếu nó có thể được chuyển tiếp nhanh. git merge --abort
không hoạt động nếu nó được sáp nhập. Nếu bạn muốn viết điều này dưới dạng một tập lệnh, thật khó xử, vì git merge
không trả lời với các mã lỗi đủ tốt để giải thích các loại xung đột khác nhau. Làm việc với một nhánh mới ngăn không cho tập lệnh bị hỏng rời khỏi repo của bạn ở trạng thái cần can thiệp thủ công. Chắc chắn bạn không thể mất bất cứ thứ gì. Nhưng nó dễ dàng hơn để xây dựng khác.
Hoàn tác hợp nhất với git rất dễ dàng, bạn thậm chí không nên lo lắng về việc chạy khô:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
EDIT: Như đã lưu ý trong các bình luận bên dưới, nếu bạn có thay đổi trong thư mục làm việc hoặc khu vực tổ chức, bạn có thể muốn bỏ chúng trước khi thực hiện các thao tác trên (nếu không chúng sẽ biến mất theo cách git reset
trên)
git branch --contains HEAD
hoặc thậm chí trực tiếp hơn, chỉ cần sử dụnggit merge --ff-only
--dry-run
sẽ không "đơn giản kiểm tra nếu hợp nhất sẽ được chuyển tiếp nhanh". Nó sẽ trả về đầu ra chính xác mà một sự hợp nhất sẽ: các tập tin, xung đột, vv Liệu điều đó có thực sự thú vị không?
git stash; git reset --hard
? @BrianPhillips
Tôi đã tạo một bí danh để làm điều này và làm việc như một cơ duyên, tôi làm điều này:
git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '
Bây giờ tôi chỉ cần gọi
git mergetest <branchname>
Để tìm hiểu nếu có bất kỳ xung đột.
Chỉ cần khác nhánh hiện tại của bạn so với nhánh từ xa, điều này sẽ cho bạn biết điều gì sẽ thay đổi khi bạn thực hiện thao tác kéo / hợp nhất.
#see diff between current master and remote branch
git diff master origin/master
Tôi sử dụng lệnh git request-pull để làm như vậy. Nó cho phép bạn xem mọi thay đổi sẽ xảy ra khi hợp nhất, nhưng không làm gì trên kho lưu trữ cục bộ hoặc từ xa .
Ví dụ, hãy tưởng tượng bạn muốn hợp nhất một nhánh có tên "Feature-x" vào nhánh chính của bạn
git request-pull master origin feature-x
sẽ cho bạn thấy một bản tóm tắt về những gì sẽ xảy ra (mà không làm gì cả):
The following changes since commit fc01dde318:
Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
Adding some layout
Refactoring
ioserver.js | 8 +++---
package.json | 7 +++++-
server.js | 4 +--
layout/ldkdsd.js | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js
Nếu bạn thêm -p
tham số, bạn cũng sẽ nhận được văn bản vá đầy đủ, chính xác như nếu bạn đang thực hiện một git diff trên mỗi tệp đã thay đổi.
master
và origin
làm trong các tùy chọn dòng lệnh, và nếu tôi là một người địa phương branch1
và muốn thực hiện một request-pull
nhánh tính năng cục bộ branch2
thì sao? Tôi vẫn cần origin
chứ? Tất nhiên, người ta luôn có thể đọc tài liệu.
Tôi ngạc nhiên không ai đề nghị sử dụng các bản vá lỗi.
Giả sử bạn muốn thử nghiệm một hợp nhất từ your_branch
vào master
(tôi giả sử bạn đã master
kiểm tra ra):
$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch
Điều đó sẽ làm các trick.
Nếu bạn gặp lỗi như
error: patch failed: test.txt:1
error: test.txt: patch does not apply
điều đó có nghĩa là bản vá không thành công và việc hợp nhất sẽ tạo ra xung đột. Không có đầu ra có nghĩa là bản vá sạch và bạn có thể dễ dàng hợp nhất chi nhánh
Lưu ý rằng điều này sẽ không thực sự thay đổi cây làm việc của bạn (tất nhiên ngoài việc tạo tệp vá lỗi, nhưng bạn có thể xóa nó một cách an toàn sau đó). Từ tài liệu áp dụng git:
--check
Instead of applying the patch, see if the patch is applicable to the
current working tree and/or the index file and detects errors. Turns
off "apply".
Lưu ý cho bất kỳ ai thông minh hơn / có kinh nghiệm với git hơn tôi: vui lòng cho tôi biết nếu tôi sai ở đây và phương pháp này hiển thị hành vi khác với hợp nhất thông thường. Có vẻ lạ là trong hơn 8 năm qua, câu hỏi này đã tồn tại, không ai có thể đề xuất giải pháp dường như rõ ràng này.
git diff master your_branch | git apply --check
.
Điều này có thể thú vị: Từ tài liệu:
Nếu bạn đã thử hợp nhất dẫn đến xung đột phức tạp và muốn bắt đầu lại, bạn có thể khôi phục bằng git merge --abort .
Nhưng bạn cũng có thể làm theo cách ngây thơ (nhưng chậm):
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(Lưu ý: Nó sẽ không hoạt động khi chỉ nhân bản vào / tmp, bạn cần một bản sao để đảm bảo rằng các thay đổi không được cam kết sẽ không xung đột).
cp -r repository/.git /tmp/repository/.git
, cd /tmp/repository
, git reset --hard
, git add --all
, git reset --hard
(đối với biện pháp tốt), git status
(để kiểm tra xem nó sạch).
Tôi biết rằng đây là một câu hỏi cũ, nhưng đây là câu hỏi đầu tiên xuất hiện trên tìm kiếm của Google.
Git giới thiệu một tùy chọn --ff-only khi hợp nhất.
Từ: http://git-scm.com/docs/git-merge
- chỉ
Từ chối hợp nhất và thoát với trạng thái khác không trừ khi CHÍNH hiện tại đã được cập nhật hoặc hợp nhất có thể được giải quyết dưới dạng chuyển tiếp nhanh.
Làm điều này sẽ cố gắng hợp nhất và chuyển tiếp nhanh, và nếu nó không thể hủy bỏ và nhắc nhở bạn rằng không thể thực hiện chuyển tiếp nhanh, nhưng khiến cho nhánh làm việc của bạn không bị ảnh hưởng. Nếu nó có thể chuyển tiếp nhanh, thì nó sẽ thực hiện hợp nhất trên nhánh làm việc của bạn. Tùy chọn này cũng có sẵn trên git pull
. Vì vậy, bạn có thể làm như sau:
git pull --ff-only origin branchA #See if you can pull down and merge branchA
git merge --ff-only branchA branchB #See if you can merge branchA into branchB
Nếu bạn muốn chuyển nhanh từ B sang A, thì bạn phải chắc chắn rằng git log B..A không cho bạn thấy gì, tức là A không có gì mà B không có. Nhưng ngay cả khi B..A có thứ gì đó, bạn vẫn có thể hợp nhất mà không có xung đột, vì vậy, ở trên cho thấy hai điều: sẽ có một chuyển tiếp nhanh, và do đó bạn sẽ không bị xung đột.
Giải pháp của tôi là hợp nhất ngược.
Thay vì hợp nhất chi nhánh của bạn vào chi nhánh "mục tiêu" từ xa, hãy hợp nhất chi nhánh đó vào chi nhánh của bạn.
git checkout my-branch
git merge origin/target-branch
Bạn sẽ thấy nếu có bất kỳ xung đột và có thể lên kế hoạch về cách giải quyết chúng.
Sau đó, bạn có thể hủy bỏ hợp nhất qua git merge --abort
hoặc (nếu không có bất kỳ xung đột và hợp nhất nào xảy ra) quay lại cam kết trước đó thông quagit reset --hard HEAD~1