programing

git이 기본적으로 빨리 감기 병합을 수행하는 이유는 무엇입니까?

nasanasas 2020. 10. 2. 22:31
반응형

git이 기본적으로 빨리 감기 병합을 수행하는 이유는 무엇입니까?


수은에서 왔기 때문에 가지를 사용하여 기능을 구성합니다. 당연히 내 역사에서도이 작업 흐름을보고 싶습니다.

git을 사용하여 새 프로젝트를 시작하고 첫 번째 기능을 마쳤습니다. 기능을 병합 할 때 git이 빨리 감기를 사용한다는 것을 깨달았습니다. 즉, 가능하면 변경 사항을 마스터 브랜치에 직접 적용하고 브랜치를 잊어 버렸습니다.

그래서 미래를 생각 해보자.이 프로젝트에서 일하는 사람은 나 뿐이다. git의 기본 접근 방식 (빨리 감기 병합)을 사용하면 내 기록이 하나의 거대한 마스터 브랜치가됩니다. 내가 모든 기능에 대해 별도의 브랜치를 사용했다는 사실은 아무도 모릅니다. 왜냐하면 결국에는 거대한 마스터 브랜치 만 갖게 될 것이기 때문입니다. 전문가 답게 보이지 않습니까?

이 이유 때문에 나는 빨리 감기 병합을 원하지 않으며 이것이 기본값 인 이유를 알 수 없습니다. 뭐가 그렇게 좋은가요?


빨리 감기 병합은 수명이 짧은 분기에 적합하지만 더 복잡한 히스토리 에서 비 빨리 감기 병합은 히스토리를 더 쉽게 이해하고 커밋 그룹을 되 돌리는 것을 더 쉽게 만들 수 있습니다.

경고 : 비 빨리 감기는 잠재적 인 부작용도 있습니다. https://sandofsky.com/blog/git-workflow.html을 검토 하고 양분 또는 비난을 깨는 '체크 포인트 커밋'으로 'no-ff'를 피하고 .NET에 대한 기본 접근 방식이어야하는지 신중하게 고려하세요 master.

대체 텍스트
( nvie.com , Vincent Driessen , " 성공적인 Git 분기 모델 " 게시 )

완성 된 기능을 개발에 통합

완성 된 기능은 다음 릴리스에 추가하기 위해 개발 브랜치에 병합 될 수 있습니다.

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

--no-ff플래그는 병합이 빨리 감기를 수행 할 수있는 경우에도, 항상 새로운 객체를 커밋 만들 병합됩니다. 이렇게하면 기능 분기의 과거 존재에 대한 정보가 손실되는 것을 방지하고 기능을 추가 한 모든 커밋을 함께 그룹화합니다.

Jakub Narębski구성에 대해서도 언급 합니다 .merge.ff

기본적으로 Git은 현재 커밋의 후손 인 커밋을 병합 할 때 추가 병합 커밋을 생성하지 않습니다. 대신 현재 분기의 끝이 빨리 감 깁니다.
로 설정 false되면이 변수는 Git에게 이러한 경우 추가 병합 커밋을 생성하도록 지시 --no-ff합니다 (명령 줄에서 옵션 을 제공하는 것과 동일 ).
' only'로 설정하면 이러한 빨리 감기 병합 만 허용됩니다 ( --ff-only명령 줄에서 옵션 을 제공하는 것과 동일 ).


빨리 감기는 다음과 같은 이유로 기본값입니다.

  • 수명이 짧은 브랜치는 Git에서 생성하고 사용하기가 매우 쉽습니다.
  • 수명이 짧은 분기는 종종 해당 분기 내에서 자유롭게 재구성 할 수있는 많은 커밋을 분리합니다.
  • 이러한 커밋은 실제로 메인 브랜치의 일부입니다. 일단 재구성되면 메인 브랜치가이를 포함하도록 빨리 감 깁니다.

그러나 하나의 주제 / 기능 브랜치에서 반복적 인 워크 플로를 예상하는 경우 (예 : 병합 한 다음이 기능 브랜치로 돌아가서 커밋을 더 추가합니다), 기본 브랜치보다는 병합 만 포함하는 것이 유용합니다. 기능 브랜치의 모든 중간 커밋.

이 경우 이러한 종류의 구성 파일을 설정할 수 있습니다 .

[branch "master"]
# This is the list of cmdline options that should be added to git-merge 
# when I merge commits into the master branch.

# The option --no-commit instructs git not to commit the merge
# by default. This allows me to do some final adjustment to the commit log
# message before it gets commited. I often use this to add extra info to
# the merge message or rewrite my local branch names in the commit message
# to branch names that are more understandable to the casual reader of the git log.

# Option --no-ff instructs git to always record a merge commit, even if
# the branch being merged into can be fast-forwarded. This is often the
# case when you create a short-lived topic branch which tracks master, do
# some changes on the topic branch and then merge the changes into the
# master which remained unchanged while you were doing your work on the
# topic branch. In this case the master branch can be fast-forwarded (that
# is the tip of the master branch can be updated to point to the tip of
# the topic branch) and this is what git does by default. With --no-ff
# option set, git creates a real merge commit which records the fact that
# another branch was merged. I find this easier to understand and read in
# the log.

mergeoptions = --no-commit --no-ff

OP는 주석에 추가합니다.

나는 [짧은] 브랜치에 대해 빨리 감기에서 어떤 의미가 있다고 생각하지만, 기본 동작으로 만드는 것은 git이 당신을 가정한다는 것을 의미합니다. 종종 [짧은] 브랜치를 가지고 있습니다. 합리적입니까?

Jefromi는 다음과 같이 대답합니다.

브랜치의 수명은 사용자마다 크게 다릅니다. 그러나 숙련 된 사용자들 사이에는 훨씬 더 짧은 분기를 갖는 경향이있을 것입니다.

To me, a short-lived branch is one that I create in order to make a certain operation easier (rebasing, likely, or quick patching and testing), and then immediately delete once I'm done.
That means it likely should be absorbed into the topic branch it forked from, and the topic branch will be merged as one branch. No one needs to know what I did internally in order to create the series of commits implementing that given feature.

More generally, I add:

it really depends on your development workflow:

  • if it is linear, one branch makes sense.
  • If you need to isolate features and work on them for a long period of time and repeatedly merge them, several branches make sense.

See "When should you branch?"

Actually, when you consider the Mercurial branch model, it is at its core one branch per repository (even though you can create anonymous heads, bookmarks and even named branches)
See "Git and Mercurial - Compare and Contrast".

Mercurial, by default, uses anonymous lightweight codelines, which in its terminology are called "heads".
Git uses lightweight named branches, with injective mapping to map names of branches in remote repository to names of remote-tracking branches.
Git "forces" you to name branches (well, with the exception of a single unnamed branch, which is a situation called a "detached HEAD"), but I think this works better with branch-heavy workflows such as topic branch workflow, meaning multiple branches in a single repository paradigm.


Let me expand a bit on a VonC's very comprehensive answer:


First, if I remember it correctly, the fact that Git by default doesn't create merge commits in the fast-forward case has come from considering single-branch "equal repositories", where mutual pull is used to sync those two repositories (a workflow you can find as first example in most user's documentation, including "The Git User's Manual" and "Version Control by Example"). In this case you don't use pull to merge fully realized branch, you use it to keep up with other work. You don't want to have ephemeral and unimportant fact when you happen to do a sync saved and stored in repository, saved for the future.

Note that usefulness of feature branches and of having multiple branches in single repository came only later, with more widespread usage of VCS with good merging support, and with trying various merge-based workflows. That is why for example Mercurial originally supported only one branch per repository (plus anonymous tips for tracking remote branches), as seen in older revisions of "Mercurial: The Definitive Guide".


Second, when following best practices of using feature branches, namely that feature branches should all start from stable version (usually from last release), to be able to cherry-pick and select which features to include by selecting which feature branches to merge, you are usually not in fast-forward situation... which makes this issue moot. You need to worry about creating a true merge and not fast-forward when merging a very first branch (assuming that you don't put single-commit changes directly on 'master'); all other later merges are of course in non fast-forward situation.

HTH

참고URL : https://stackoverflow.com/questions/2850369/why-does-git-perform-fast-forward-merges-by-default

반응형