Git: 구체적인 약속을 기반으로 하는 방법은 무엇입니까?
다른 지점의 헤드가 아닌 특정 커밋을 기반으로 합니다.
A --- B --- C master
\
\-- D topic
로.
A --- B --- C master
\
\-- D topic
대신에
A --- B --- C master
\
\-- D topic
어떻게 하면 그것을 달성할 수 있을까요?
원하는 커밋에 임시 분기를 만든 다음 간단한 형식으로 rebase를 사용하여 --to 매개변수를 사용하지 않도록 할 수 있습니다.
git branch temp master^
git checkout topic
git rebase temp
git branch -d temp
직접적인 접근 방식을 취할 수도 있습니다.
git checkout topic
git rebase <commitB>
"to" 옵션을 사용합니다.
git rebase --onto master^ D^ D
OR
git rebase --onto <commitB> <commitA> <commitD>
세 개의 마지막 인수는 다음을 의미합니다.
- 대상(새 부모, 여기는 commitB),
- start-after(현재-상위, 이동할 첫 번째 커밋의 상위),
- 및 End-commit(이동할 마지막 커밋).
위의 jsz의 의견은 저에게 많은 고통을 덜어주었기 때문에, 다음은 제가 다른 약속 위에 커밋을 재배치/이동하는 데 사용해 온 단계별 리셉션입니다.
- 재배치(이동)할 분기의 이전 분기점을 찾습니다. 이전 분기점을 이전 상위라고 합니다.위의 예는 A입니다.
- 분기를 이동할 상위에서 커밋을 찾습니다. 새 상위라고 합니다.예제에서 그것은 B입니다.
- 이동하는 지점에 있어야 합니다.
- 기본 재배치 적용:
git rebase --onto <new parent> <old parent>
위의 예에서는 다음과 같이 간단합니다.
git checkout topic
git rebase --onto B A
토픽 솔루션
일 수 .topic
이미 체크아웃됨):
git rebase --onto B master
git rebase --onto master~1 master
git rebase --onto B A
git rebase --onto B C
git rebase --onto B
한다면topic
체아웃않다니았습을 . 그냥 추가하시면 됩니다.topic
다음과 같이 명령(마지막 명령 제외)에 적용됩니다.
git rebase --onto B master topic
또는 다음을 사용하여 지점을 먼저 확인하십시오.
git checkout topic
모든 커밋 문자열을 대상 커밋으로 재배치
설명서에서 발췌한 명령어의 기본 형식은 다음과 같습니다.
git rebase --onto <Target> [<Upstream> [<Branch>]]
<Branch>
는 선택 사항이며 나머지 명령을 실행하기 전에 지정된 분기를 체크아웃하는 것이 전부입니다.기본값을 변경할 분기를 이미 체크아웃한 경우에는 이 항목이 필요하지 않습니다.로 "" " " " " 를 .<Upstream>
를 지정하기 <Branch>
오짓트는 당신이 지정하고 있다고 생각할 것입니다.<Upstream>
.
<Target>
일련의 커밋을 연결할 커밋입니다.분기 이름을 제공할 때는 해당 분기의 헤드 커밋을 지정하기만 하면 됩니다. <Target>
이동할 커밋 문자열에 포함되지 않는 커밋일 수 있습니다.예:
A --- B --- C --- D master
\
\-- X --- Y --- Z feature
분기를 전체피분기이동면다음선수없다습니택할을려를 할 수 .X
,Y
,Z
또는feature
▁the로서<Target>
모두 이동되는 그룹 내부의 커밋이기 때문입니다.
<Upstream>
두 가지 다른 것을 의미할 수 있기 때문에 특별합니다.체크아웃된 분기의 상위 항목인 커밋인 경우, 컷포인트 역할을 합니다.제공한 은 제가제공한예, 이은모것아닙이다니든서에것이입니다.C
,D
또는master
커밋은 커밋모든후 뒤에 있습니다.<Upstream>
체크아웃한 지점의 헤드가 이동할 때까지.
만약 만지면, 에약.<Upstream>
이 상위 항목이 아닙니다. 그러면 Git는 체크아웃된 분기가 있는 공통 상위 항목을 찾을 때까지 지정된 커밋에서 체인을 백업합니다(찾을 수 없는 경우 중단됨). 경우에는 우의경우,<Upstream>
B
,C
,D
또는master
모든 것이 커밋으로 이어질 것입니다.B
커트 포인트 역할을 하는 <Upstream>
. 는 그 자 가 선 는 경 지 않 우 웃 된 아 분 살 봅 펴 니 다 를 부 모 의 기 체 크 은 되 정 지 체 명 택 적 인 이 령 며 ▁which ▁is ▁at ▁of ▁branch ▁entering▁equival▁the▁out▁the다 ▁is ▁if ▁itself그it▁checked▁then▁of▁and니 ▁an봅펴it▁parent살▁g▁looks,▁the▁it를▁command모부자 이는 입력하는 것과 같습니다.master
.
Git가 잘라내고 이동할 커밋을 선택했으므로 Git는 이 커밋을 적용합니다.<Target>
대상에 이미 적용된 항목을 건너뜁니다.
흥미로운 예와 결과
이 시작점 사용:
A --- B --- C --- D --- E master
\
\-- X --- Y --- Z feature
git rebase --onto D A feature
커밋을 합니다.B
,C
,X
,Y
,Z
지는저를D
그리고 결국 건너뛰게 됩니다.B
그리고.C
이미 적용되었기 때문입니다.git rebase --onto C X feature
커밋을 합니다.Y
그리고.Z
지는저를C
커밋을 합니다.X
은 더간한해은입니다.git rebase <SHA1 of B> topic
은 당신의 이은당위상작이동다니합관없이 에 있든지 상관없이 작동합니다.HEAD
사실은.
Gitrebase 문서에서 이 동작을 확인할 수 있습니다.
<upstream>
비교할 업스트림 분기입니다.기존 지점 이름뿐만 아니라 유효한 커밋일 수 있습니다.현재 분기에 대해 구성된 업스트림으로 기본 설정됩니다.
You might be thinking what will happen if I mention SHA1 of
topic
too in the above command ?
git rebase <SHA1 of B> <SHA1 of topic>
이것도 작동하지만 베이스를 재조정하면 작동하지 않습니다.Topic
이렇게 생성된 새 분기를 가리킵니다.HEAD
분리 상태가 됩니다.따라서 여기서 이전 버전을 수동으로 삭제해야 합니다.Topic
그리고 rebase에 의해 생성된 새 분기에 새 분기 참조를 만듭니다.
기본 재배치가 매우 기본적이기 때문에, 여기 네스토르 밀랴예프의 대답이 확장되었습니다.애덤 다이미트룩의 답변에서 나온 jsz와 사이먼 사우스의 코멘트를 결합하면 다음과 같은 명령이 생성됩니다.topic
분기여관분기이계없에부에서 master
A
또는C
:
git checkout topic
git rebase --onto <commit-B> <pre-rebase-A-or-post-rebase-C-or-base-branch-name>
않으면 커밋합니다).B
).
예:
# if topic branches from master commit A:
git checkout topic
git rebase --onto <commit-B> <commit-A>
# if topic branches from master commit C:
git checkout topic
git rebase --onto <commit-B> <commit-C>
# regardless of whether topic branches from master commit A or C:
git checkout topic
git rebase --onto <commit-B> master
마지막 명령어는 제가 주로 사용하는 명령어입니다.
다을사용답추가를 사용하여 --onto
:
저는 논쟁의 순서를 암기한 적이 없어서 다음과 같은 작은 도우미 스크립트를 작성했습니다.
Git: 한 베이스에서 다른 베이스로 분기를 재배치하고 다른 베이스의 커밋을 남깁니다.
용도:
moveBranch <branch> from <previous-base> to <new-base>
이 작업은 다음과 같습니다.
git rebase --onto "$ONTO" "$FROM" "$WHAT"
그 외에도, 유사한 목적으로 사용할 수 있는 한 가지 솔루션은 다음과 같습니다.cherry-pick
일련의 커밋:
git co <new-base>
git cherry-pick <previous-base>..<branch>
git branch -f branch
같은 효과가 더 적은 것입니다.은 " " " "에서 합니다.<previous-branch>
그 자체로, 그래서 그것은 다음과 다음에 대한 약속을 포함하여 체리-링합니다.<branch>
.
위에서 설명한 솔루션을 혼합하여 사용했습니다.
$ git branch temp <specific sha1>
$ git rebase --onto temp master topic
$ git branch -d temp
저는 읽고 이해하는 것이 훨씬 더 쉽다는 것을 알았습니다.승인된 솔루션은 병합 충돌(손으로 해결하기에는 너무 귀찮음)로 이어집니다.
$ git rebase temp
First, rewinding head to replay your work on top of it...
Applying: <git comment>
Using index info to reconstruct a base tree...
M pom.xml
.git/rebase-apply/patch:10: trailing whitespace.
<some code>
.git/rebase-apply/patch:17: trailing whitespace.
<some other code>
warning: 2 lines add whitespace errors.
Falling back to patching base and 3-way merge...
Auto-merging pom.xml
CONFLICT (content): Merge conflict in pom.xml
error: Failed to merge in the changes.
Patch failed at 0001 <git comment>
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
git rebase --onto <commitB> <commitA> <commitD>
사실로 커밋commit, 마지매변커수밋로사개실막커▁as)을 합니다.<commitD>
이름 (지점이름대신▁()대신이▁) ())topic
지점을 .
A --- B --- C master
\ \
\ -- D' <detached HEAD>
\
\-- D topic
제외하고는...Git 2.36 이전의 경우에는 그렇지 않습니다.
언제git rebase $base $non_branch_commit
(man)$base
조상또그이다.$non_branch_commit
Git 2.36 (Q2 2022)으로 수정된 현재 분기를 수정했습니다.
commit bdff97a, 77ab58c(2022년 3월 18일)를 참조하십시오.john-cai
(주니오 C 하마노에 의해 합병 -- -- f818536, 2022년 3월 29일 커밋에서)
rebase
세트REF_HEAD_DETACH
checkout_up_to_date()
신고자: 마이클 맥클라이먼
사인 오프 바이: 존 카이
어디서
git rebase A B
(man)B
. 가 밋이아에서 하면 안 . 헤드가 분리된 것처럼 행동해야 합니다.B
그리고 분리된 HEAD는 그 위에 다시 기반을 두었습니다.A
.그러나 버그는 현재 분기를 가리키도록 덮어씁니다.
B
,time,t제B
는 의후니다의 입니다.A
(즉, 기본 재배치는 결국 빨리 진행됩니다.)
원본 버그 보고서는 이 스레드를 참조하십시오.의 콜
checkout_up_to_date()
과 같습니다.
cmd_rebase()
->checkout_up_to_date()
-> -> -> reset_head() -> update_refs() -> update_refs()때
B
oid이며, 는 oid, rebase는 oid를 합니다.head_name
rebase_options
NULL
.
은 이값 다의 멤를통버해이의 이 콜 됩니다.reset_head_opts
또시작기로NULL
update_refs()
.그리고나서
update_refs()
을 확인하여 branchrops.dll을 합니다.
한다면ropts.branch
이라NULL
은 은것라고 부릅니다.update_ref()
HEAD를 업데이트합니다.
그러나, 이 시점에서, 리베이스의 관점에서, 우리는 분리된 HEAD를 원합니다.
하지만, 그 이후로checkout_up_to_date()
를 .RESET_HEAD_DETACH
깃발,update_ref()
호출은 HEAD를 참조하고 가리키는 분기를 업데이트합니다.
우리는 대신 B에서 HEAD가 분리되기를 원합니다.다음을 추가하여 이 버그를 수정합니다.
RESET_HEAD_DETACH
기어들어가다.checkout_up_to_date
만약 B가 유효한 분기가 아니라면, 그래서 그것은 한 번.reset_head()
출들update_refs()
은 은것라고 부릅니다.update_ref()
와 함께REF_NO_DEREF
이는 HEAD를 방어하고 HEAD가 가리키는 분기를 업데이트하는 대신 HEAD를 직접 업데이트합니다.
다른 방법이 있거나 둘 이상의 커밋으로 다시 이동하려는 경우.
다음은 다음과 같은 예입니다.n
커밋 수:
git branch topic master~n
이 질문을 위해 이 작업을 수행할 수도 있습니다.
git branch topic master~1
명령어는 명은에작니다동합게벽하완에서 합니다.git version 2.7.4
다른 버전에서는 테스트하지 않았습니다.
언급URL : https://stackoverflow.com/questions/7744049/git-how-to-rebase-to-a-specific-commit
'source' 카테고리의 다른 글
Python에서 체인 메서드 호출 들여쓰기 스타일 (0) | 2023.07.18 |
---|---|
ORACLE/SQL Server의 마이너스와 예외 차이 (0) | 2023.07.18 |
.htaccess / Apache2를 사용하여 간단한 php 애플리케이션으로 하위 디렉토리에서 워드프레스 애플리케이션을 구성하는 방법은 무엇입니까? (0) | 2023.07.18 |
VBA 사용자 양식에 날짜 선택기를 추가하는 방법 (0) | 2023.07.18 |
열 설명 추가 (0) | 2023.07.18 |