Program Tip

`git merge`와`git merge --no-ff`의 차이점은 무엇입니까?

programtip 2020. 9. 28. 09:55
반응형

`git merge`와`git merge --no-ff`의 차이점은 무엇입니까?


를 사용 gitk log하면 둘의 차이점을 찾을 수 없었습니다. 차이점을 어떻게 관찰 할 수 있습니까 (git 명령 또는 일부 도구 사용)?


--no-ff플래그 방지 git merge그것이 당신의 전류가 감지 경우 "빨리 감기"실행에서 HEAD당신이 병합하려는 커밋의 조상이다. 빨리 감기는 병합 커밋을 구성하는 대신 git이 들어오는 커밋을 가리 키도록 분기 포인터를 이동하는 경우입니다. 이것은 일반적으로 git pull로컬 변경없이 a 수행 할 때 발생합니다 .

그러나 때때로 특정 분기 토폴로지를 유지하기를 원하기 때문에 이러한 동작이 발생하지 않도록하고 싶을 때가 있습니다 (예 : 토픽 분기에서 병합하고 히스토리를 읽을 때 그렇게 보이는지 확인하려는 경우). 그렇게하기 위해서는, 당신은 통과 할 수 --no-ff플래그를하고 git merge것입니다 항상 빨리 감기 대신 병합을 구성.

마찬가지로, 명시 적으로 빨리 감기를 위해 git pull또는 use 를 실행하고 git merge빨리 감기를 할 수없는 경우 구제 조치를 취하려면 --ff-only플래그를 사용할 수 있습니다 . 이런 식으로 git pull --ff-only생각하지 않고 정기적으로 같은 일을 할 수 있으며 오류가 발생하면 다시 돌아가 병합 또는 리베이스할지 결정할 수 있습니다.


이 질문에 대한 그래픽 답변

다음은 사용에 대한 명확한 설명과 그래픽 그림 이있는 사이트 입니다 git merge --no-ff.

git merge --no-ff와 git merge의 차이점

이것을 볼 때까지 나는 git과 함께 완전히 길을 잃었습니다. 을 사용 --no-ff하면 기록을 검토하는 사람 이 작업하기 위해 체크 아웃 한 브랜치 를 명확하게 볼 수 있습니다 . (그 링크는 github의 "네트워크"시각화 도구를 가리 킵니다.) 그리고 여기 일러스트레이션과 관련된 또 다른 훌륭한 참고 자료 가 있습니다. 이 참조는 git에 익숙하지 않은 사람들에게 초점을 맞춘 첫 번째 참조를 멋지게 보완합니다.


나 같은 newbs에 대한 기본 정보

당신이 나와 같고 Git-guru가 아니라면 여기에 내 대답 은 git의 추적에서 파일을 삭제하지 않고 파일을 로컬 파일 시스템에서 삭제하지 않고 처리하는 방법에 대해 설명합니다. 또 다른 새로운 상황은 현재 코드를 얻는 것인데, 여전히 나를 피할 수 있습니다.


워크 플로 예

내 웹 사이트에 패키지를 업데이트하고 내 워크 플로를보기 위해 내 노트로 돌아 가야했습니다. 이 답변에 예제를 추가하는 것이 유용하다고 생각했습니다.

git 명령의 내 워크 플로우 :

git checkout -b contact-form
(do your work on "contact-form")
git status
git commit -am  "updated form in contact module"
git checkout master
git merge --no-ff contact-form
git branch -d contact-form
git push origin master

아래 : 설명을 포함한 실제 사용.
참고 : 아래 출력은 잘립니다. git은 매우 장황합니다.

$ git status
# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   ecc/Desktop.php
#       modified:   ecc/Mobile.php
#       deleted:    ecc/ecc-config.php
#       modified:   ecc/readme.txt
#       modified:   ecc/test.php
#       deleted:    passthru-adapter.igs
#       deleted:    shop/mickey/index.php
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       ecc/upgrade.php
#       ecc/webgility-config.php
#       ecc/webgility-config.php.bak
#       ecc/webgility-magento.php

위의 3 가지 사항에 유의하십시오.
1) 출력에서 ​​새 파일 추가를 포함하여 ECC 패키지 업그레이드의 변경 사항을 볼 수 있습니다.
2) 또한 /ecc이 변경 사항과 관계없이 삭제 한 두 개의 파일 ( 폴더에 없음)이 있습니다. 파일 삭제를와 혼동하는 대신 나중에 해당 파일의 삭제를 반영하기 위해 ecc다른 cleanup분기를 만들 것 입니다.
3) 내 작업 흐름을 따르지 않았습니다! ecc가 다시 작동하도록 노력하는 동안 git을 잊어 버렸습니다.

아래 : git commit -am "updated ecc package"일반적으로 하는 모든 항목을 포함하는 대신 /ecc폴더에 파일 만 추가하고 싶었습니다 . 삭제 된 파일은 내.의 일부는 git add아니지만 이미 git에서 추적 되었기 때문에이 분기의 커밋에서 제거해야합니다.

$ git checkout -b ecc
$ git add ecc/*
$ git reset HEAD passthru-adapter.igs
$ git reset HEAD shop/mickey/index.php
Unstaged changes after reset:
M       passthru-adapter.igs
M       shop/mickey/index.php

$ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks"

$ git checkout master
D       passthru-adapter.igs
D       shop/mickey/index.php
Switched to branch 'master'
$ git merge --no-ff ecc
$ git branch -d ecc
Deleted branch ecc (was 98269a2).
$ git push origin master
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 59.00 KiB, done.
Total 14 (delta 10), reused 0 (delta 0)
To git@github.com:me/mywebsite.git
   8a0d9ec..333eff5  master -> master



위의 자동화를위한 스크립트

이 프로세스를 하루에 10 번 이상 사용하면서 명령을 실행하는 배치 스크립트를 작성 했으므로 git_update.sh <branch> <"commit message">위 단계를 수행 하는 데 거의 적합한 스크립트를 만들었습니다 . 다음은 해당 스크립트 의 Gist 소스 입니다.

대신 git commit -am생성 된 "수정 된"목록에서 파일을 git status선택한 다음이 스크립트에 붙여 넣습니다. 수십 번의 편집을했지만 변경 사항을 그룹화하는 데 도움이되는 다양한 브랜치 이름을 원했기 때문입니다.


--no-ff옵션은 빨리 감기 병합이 발생하지 않고 항상 새 커밋 객체가 생성되도록 합니다. git이 기능 브랜치의 기록을 유지하도록하려면 바람직 할 수 있습니다.             git merge --no-ff 대 git merge위 이미지에서 왼쪽은 사용 후 git 히스토리 git merge --no-ff의 예이고 오른쪽 git merge은 ff 병합이 가능한 곳 을 사용한 예입니다 .

편집 :이 이미지의 이전 버전은 병합 커밋에 대한 단일 부모 만 표시했습니다. 병합 커밋에는 git이 "기능 브랜치"및 원래 브랜치의 기록을 유지하는 데 사용하는 여러 상위 커밋 이 있습니다. 여러 상위 링크는 녹색으로 강조 표시됩니다.


병합 전략

Explicit Merge: Creates a new merge commit.(This is what you will get if you used --no-ff.)

여기에 이미지 설명 입력

Fast Forward Merge: Forward rapidly, without creating a new commit:

여기에 이미지 설명 입력

Rebase: Establish a new base level:

여기에 이미지 설명 입력

Squash: Crush or squeeze (something) with force so that it becomes flat:

여기에 이미지 설명 입력


This is an old question, and this is somewhat subtly mentioned in the other posts, but the explanation that made this click for me is that non fast forward merges will require a separate commit.


The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature

참고 URL : https://stackoverflow.com/questions/9069061/what-is-the-difference-between-git-merge-and-git-merge-no-ff

반응형