Nice programing

'git rebase -i'를 사용하여 분기의 모든 변경 사항을 리베이스하려면 어떻게해야합니까?

nicepro 2020. 12. 13. 11:08
반응형

'git rebase -i'를 사용하여 분기의 모든 변경 사항을 리베이스하려면 어떻게해야합니까?


예를 들면 다음과 같습니다.

>git status
# On branch master
nothing to commit (working directory clean)
>git checkout -b test-branch
>vi test.c
>git add test.c
>git commit -m "modified test.c"
>vi README
>git add README
>git commit -m "modified README"

이제이 git rebase -i분기에 대한 모든 커밋을 리베이스 할 수 있는 ' ' 를 수행하고 싶습니다 . ' git rebase -i HEAD~MASTER' 와 같은 것이 있습니까? 나는 ' git rebase -i HEAD~2'을 할 수 있다고 생각 하지만 실제로 얼마나 많은 커밋이 이루어 졌는지 세고 싶지 않습니다. ' git rebase -i sha1' 도 할 수 있지만 첫 번째 커밋 sha1을 찾기 위해 git log를 살펴보고 싶지 않습니다. 어떤 아이디어?


시도해 보셨습니까 git rebase -i master?


좋아, 나는 분기가 "기능"이라고 가정하고 "마스터"에서 분기되었다.

merge-base라는 작은 git 명령이 있습니다. 두 개의 커밋이 필요하며 두 커밋의 첫 번째 공통 조상을 제공합니다. 그래서...

git merge-base feature master

...이 두 커밋의 첫 번째 공통 조상을 제공합니다. 커밋을 git rebase -i에 전달할 때 어떤 일이 발생하는지 추측하십시오.

git rebase -i `git merge-base feature master`

마스터 및 기능 브랜치의 첫 번째 공통 조상에서 상호 작용하는 리베이스. 이익! ;)


제공된 모든 솔루션의 문제는 첫 번째 커밋에서 리베이스 할 수 없다는 것입니다. 첫 번째 커밋 해시가 XYZ이고 다음을 수행하는 경우 :

git rebase -i XYZ

두 번째 커밋부터 리베이스합니다.

첫 번째 커밋에서 리베이스하려면 다음을 수행하십시오.

git rebase -i --root

다른 플랫폼에서 gitk (* nix) 또는 gitx (OS X) 또는 이와 유사한 것을 사용하고 어떤 커밋이 브랜치의 루트인지 살펴보세요. 그런 다음 다음을 실행하십시오.

git rebase -i <the SHA hash of the root commit>

예를 들어 gitx를 사용하여 검사 한 저장소가 있습니다.

gitx 화면 캡

이제 루트 해시를 알았으므로 다음을 실행할 수 있습니다.

git rebase -i 38965ed29d89a4136e47b688ca10b522b6bc335f

그리고 내 에디터가 이걸로 튀어 나와 내가 원하는대로 재배치 / 스쿼시 / 무엇이든 할 수 있습니다.

pick 50b2cff File 1 changes.
pick 345df08 File 2 changes.
pick 9894931 File 3 changes.
pick 9a62b92 File 4 changes.
pick 640b1f8 File 5 changes.
pick 1c437f7 File 6 changes.
pick b014597 File 7 changes.
pick b1f52bc File 8 changes.
pick 40ae0fc File 9 changes.

# Rebase 38965ed..40ae0fc onto 38965ed
#
# Commands:
#  pick = use commit
#  edit = use commit, but stop for amending
#  squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

I'm sure there's some magic way to convince git to figure out the root of the tree automatically, but I don't know what it is.

EDIT: That magic is this:

git log master..other_feature | cat

Which will show you all the commits on that branch, and piping to cat will disable the pager so you see the first commit immediately.

EDIT: combining the above gives a fully automated solution:

git rebase -i  `git log master..other_feature --pretty=format:"%h" | tail -n 1`~

The problem with rebasing from a different branch

The problem with git rebase -i master is that you may have merge conflicts that you don't necessarily want to deal with at the moment, or you may fix a conflict in one commit, only to fix it again in another commit during the course of the rebase.

The problem with rebasing from a known commit

The whole problem here is that you have to know which commit you have to refer to, either by its SHA, or HEAD~x, etc. This is only a minor annoyance but it is an annoyance.

The better way

If you instead want to rebase all the commits in your current branch, since the most recent commit it shared with its parent branch, you can add the following alias to .gitconfig:

rbi = !sh -c \"git rebase -i `git merge-base $1 HEAD`\" -

Usage

git rbi parentBranch

How it works

This alias is just a shell script, that is using an argument which refers to the parent branch. That argument is passed into git merge-base in order to determine the most recent shared commit between that branch, and the current branch.


Since Git v1.7.10, you can just run git rebase without argument, and it will find the fork point and rebase your local changes on the upstream branch.

You need to have configured the upstream branch for this to work (i.e. git pull without argument should work).

For more details, see the docs for git rebase:

If is not specified, the upstream configured in branch..remote and branch..merge options will be used (see git-config[1] for details) and the --fork-point option is assumed. If you are currently not on any branch or if the current branch does not have a configured upstream, the rebase will abort.


A general solution (if you don't know the name of the upstream branch) is:

git rebase -i @{upstream}

Note that if your upstream (probably a tracking branch) has updated since you last rebased, you will pull in new commits from the upstream. If you don't want to pull in new commits, use

git rebase -i `git merge-base --all HEAD @{upstream}`

but that is a bit of a mouthful.


git rebase -i --onto @{u}... @{u}

HEAD의 단일 병합 지점과 업스트림에없는 HEAD의 모든 커밋을 포함하는 업스트림에서 시작하는 대화 형 리베이스.

즉, 정확히 원하는 것입니다.

참고 URL : https://stackoverflow.com/questions/363908/how-do-i-use-git-rebase-i-to-rebase-all-changes-in-a-branch

반응형