git 병합을 수행 할 때 특정 커밋을 제외 할 수 있습니까?
릴리스 브랜치에서 마스터 브랜치로 병합하려고하고 릴리스 브랜치에 마스터 브랜치에 포함하고 싶지 않은 커밋이 있다고 가정 해 보겠습니다. 하나 이상의 커밋이 병합되지 않도록 병합하는 방법이 있습니까?
지금까지 나의 전략은 (마스터에서) 다음을 수행하는 것입니다.
git merge --no-commit release-branch
# Resolve conflicts and apply reverse patch of the commits that I don't want included
git commit # Edit commit message so that it lists the commits that have been reverse-patched
이 작업을 수행하는 더 좋은 방법이 있습니까?
새 분기를 만들고 대화식으로 분기를 리베이스하고 원하지 않는 커밋을 삭제 한 다음 병합합니다.
다시 해싱하지 않고 브랜치 중간에서 변경 사항을 가져올 수는 없지만 나중에 병합 할 때 동일한 변경 사항이 표시되면 올바른 일이 발생합니다 (예 : 체리 따기 및 기타 항목).
Pro Git 책 에서 저에게 맞는 솔루션을 찾았습니다 .
파일을 제외하고 싶다고 가정 해 보겠습니다 config.php
.
지점 A :
다음
.gitattributes
줄을 사용하여 동일한 디렉토리에 이름이 지정된 파일을 만듭니다config.php merge=ours
.. 이것은 파일을 병합 할 때 사용할 전략을 git에게 알려줍니다. 이 경우 항상 버전을 유지합니다. 병합하려는 분기의 버전..gitattributes
파일 추가 및 커밋
분기 B : 1-2 단계 반복
지금 병합 해보세요. 파일은 그대로 두어야합니다.
버그를 수정하고 새 버전을 빌드하는 지원 지점이있는 경우. 마스터에서는 새 버전을 자주 빌드하는 다음 버전이 있습니다.
새 버전을 빌드 할 때마다 일부 파일의 버전을 변경하고 새 파일을 커밋하고 태그를 만들고 푸시합니다. 이제 지원 에서 마스터로 병합 하면 버전 정보가 포함 된 파일에서 항상 충돌이 발생합니다.
버전 정보가 포함 된 파일에 버전 정보 만 포함되어있는 경우 fcurella의 대답으로 이동할 수 있습니다. 그러나 실제로 병합 가능한 정보 (pom.xml, gradle.properties, MANIFEST.MF, ...)도 포함 할 수있는 경우 몇 가지 추가 작업을 수행해야합니다.
다음 예를 사용합니다.
C---D*---E---F* support
/
A---B---G---H*---I master
별표가있는 커밋에는 병합 중에 무시해야하는 버전 변경으로 인한 변경 사항 만 포함됩니다.
버전 빌드로 인한 병합 충돌없이 지원 을 마스터에 병합하려면 다음 중 하나를 수행 할 수 있습니다.
여러 병합 커밋
git checkout master
git merge C
git merge D -s ours
git merge E
git merge F -s ours
-s ours
인수를 사용하여 git에게 작업 공간을 변경하지 않고 병합 만 기록하도록 지시합니다. 이것은 svn 옵션 과 비슷 합니다--record-only
.
위의 결과는 다음과 같은 레이아웃이됩니다.
-------------C---D*---E---F* support
/ \ \ \ \
A---B---G---H*---I---J---K----L---M master
Cherry-Pick을 사용한 하나의 병합 커밋
git checkout master
git merge support -s ours --no-commit
git cherry-pick C E --no-commit
git commit -m 'merged support into master'
먼저 병합을 시작하지만 작업 공간을 변경하지 않고 병합 커밋을 수행하지 않고 병합중인 기록 만 기록합니다. 그런 다음 다시 커밋없이 병합 할 커밋을 선택합니다. 마지막으로 병합을 수행합니다.
위의 결과는 다음과 같은 레이아웃이됩니다.
C---D*---E---F* support
/ \
A---B---G---H*---I---J master
체리 따기를 자동화 할 수도 있습니다.
git checkout master
git merge support -s ours --no-commit
for id in `git log support --reverse --not HEAD --format="%H [%an] %s" |
grep -v "bump version" |
sed "s/\(\w*\)\s.*/\1/g"`
do
git cherry-pick --no-commit $id
done
git commit -m 'merged support into master'
The reason why this can't be done directly is that every commit contains links to the parent commits (typically just one but several for merges). That way if you have one commit (by its SHA1 sum) the whole history is also fixed as the parents also contain links to their parents and so on. So the only way to leave out patches in the history is to write a new one. git rebase -i on a newly created branch is probably the easiest way of achieving that.
It's also possible to modify .git/info/attributes file and keep it inside .git folder instead of adding .gitattribute files all over that will require adding them to source control eventually.
The main question is: how do you want to represent the commits you want to skip?
- sneakily hide them (not my favorite)
- explicitly skip them
- explicitly undo them
Unfortunately no. 2 is impossible to express in the history graph.
No. 1 is possible, but I would never do that: a merge commit can contain changes. – Normally a merge commit points to the result of the merge of two more more branches: all things developed in those branches should be in the code after the merge (i.e. in the code pointed to by the merge commit). And nothing else should be in this commit.
But surprise, surprise, you can change the entire code base and represent it as a merge. The effect of a merge is two-fold: it merges the history tree and it should merge two code bases. The former it does for sure (otherwise no-one calls it a merge), for the latter it might fail, e.g. when a merge conflict arose and it was resolved wrongly (then the code bases were not merged properly).
Some of the other answers suggest this hiding. I recommend the explicit way: merge plus revert commits.
If you only want to exclude some commits that are at the end, you can just commit to a specific commit number:
git checkout partlyMergedFrom
git whatchanged
--> find the commit hash up to where you want to merge
git checkout partlyMergedInto
git merge e40a0e384f58409fe3c864c655a8d252b6422bfc
git whatchanged
--> check that you really got all the changes you want to have
'Programing' 카테고리의 다른 글
ANTLR4에서 오류 처리 (0) | 2020.11.11 |
---|---|
ITMS-90535 최신 Google 로그인 SDK로 iOS 앱을 게시 할 수 없습니다. (0) | 2020.11.11 |
어레이의 중복 여부를 어떻게 확인합니까? (0) | 2020.11.10 |
오류 : psycopg2.extensions라는 모듈이 없습니다. (0) | 2020.11.10 |
Pandas 집계 함수에서 반환 된 열의 이름을 지정 하시겠습니까? (0) | 2020.11.10 |