source

Git을 사용하여 최신 커밋을 새 브랜치로 이동

nicesource 2023. 4. 14. 21:54
반응형

Git을 사용하여 최신 커밋을 새 브랜치로 이동

마스터에 대한 최근 커밋을 새 브랜치로 이동하고 해당 커밋이 이루어지기 전에 마스터를 리셋하려면 어떻게 해야 합니까? 예:

master A - B - C - D - E

이를 위해:

newbranch     C - D - E
             /
master A - B 

기존 분기로 이동

커밋을 기존 브랜치로 이동하려면 다음과 같이 됩니다.

git checkout existingbranch
git merge branchToMoveCommitFrom
git checkout branchToMoveCommitFrom
git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work.
git checkout existingbranch

하기 전에 커밋되지 않은 편집 하기 위해 를 사용합니다.git stash 않은 편집 을 커밋되지 않은 상태로 수 있습니다.git stash pop

새로운 브랜치로 이동

경고: 이 방법은 첫 번째 명령으로 새 분기를 만들기 때문에 작동합니다.git branch newbranch커밋을 기존 브랜치로 이동하려면 변경을 기존 브랜치에 병합한 후 실행해야 합니다.git reset --hard HEAD~3(위의 기존 브랜치로 이동을 참조하십시오).먼저 변경 내용을 병합하지 않으면 변경 내용이 손실됩니다.

다른 상황이 발생하지 않는 한 분기 및 롤백으로 쉽게 수행할 수 있습니다.

# Note: Any changes not committed will be lost.
git branch newbranch      # Create a new branch, saving the desired commits
git checkout master       # checkout master, this is the place you want to go back
git reset --hard HEAD~3   # Move master back by 3 commits (Make sure you know how many commits you need to go back)
git checkout newbranch    # Go to the new branch that still has the desired commits

하지만 얼마나 많은 커밋을 되돌릴지는 확실히 해야 합니다., 신, 대, 대, 대, 대, 대, 대, 대, altern, altern, altern, altern.HEAD~3마스터(/current) 브랜치로 "복귀할" 커밋(또는 원본/마스터참조)의 해시만 제공합니다.다음은 예를 제시하겠습니다.

git reset --hard a1b2c3d4

*1 마스터 브랜치에서의 커밋만 "실패"합니다만, 새로운 브랜치에서는 커밋을 얻을 수 있으므로 안심하십시오.

마지막으로 최신 변경 내용을 메인 리포트에 강제 적용해야 할 수 있습니다.

git push origin master --force

경고: Git 버전 2.0 이후, 나중에 사용하는 경우git rebasemaster )이 할 수 --no-fork-point이월된 커밋이 손실되지 않도록 기본 재배치 시 옵션을 선택합니다. 있다branch.autosetuprebase alwaysset를 지정하면 가능성이 높아집니다.자세한 내용은 John Mellor의 답변을 참조하십시오.

(처음처럼) 왜 기능하는지 궁금하신 분들을 위해:

C로 돌아가서 D와 E를 새로운 브랜치로 이동하려고 합니다.첫 번째는 다음과 같습니다.

A-B-C-D-E (HEAD)
        ↑
      master

★★★ git branch newBranch:

    newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

★★★ git reset --hard HEAD~2:

    newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

브랜치는 포인터일 뿐이므로 마스터는 마지막 커밋을 가리켰습니다.new Branch를 작성했을 때 마지막 커밋에 대한 새로운 포인터를 작성했을 뿐입니다.그 후,git reset마스터 포인터를 2개의 커밋 뒤로 이동했습니다.그러나 new Branch를 이동하지 않았기 때문에 원래 이동했던 커밋을 나타냅니다.

일반적으로...

이 경우 sykora에 의해 노출되는 방법이 가장 좋은 옵션입니다.하지만 때로는 가장 쉬운 방법이 아니며 일반적인 방법이 아닙니다.일반적인 방법으로는 git cherry-pick을 사용합니다.

OP가 원하는 것을 달성하려면 다음 2단계 프로세스를 수행합니다.

1 - 1 - 텝텝 - a a a a에 적어 .newbranch

실행

git checkout master
git log

커밋의 커밋에서 newbranch여기에서는 다음을 사용합니다.
C:9aa1233
D ★★★453ac3d
E 커: :612ecb3

주의: 처음 7자 또는 커밋 해시 전체를 사용할 수 있습니다.

2 - 텝 -2 - 이 the the .newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

OR(Git 1.7.2+에서는 범위 사용)

git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233

git cherry-pick은 이 세 가지 커밋을 새로운 브랜치에 적용합니다.

대부분의 이전 답변은 위험할 정도로 틀렸습니다!

이 조작은 하지 말아 주세요.

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

에 할 때git rebase (오류)git pull --rebase의 커밋은 됩니다.newbranch () (이것들)

대신 다음을 수행합니다.

git reset --keep HEAD~3
git checkout -t -b newbranch
git cherry-pick ..HEAD@{2}
  • 커밋 3」, 「3」)를합니다.--keep~와 --hard단, 커밋되지 않은 변경을 폐기하는 것보다 실패하는 것이 안전합니다.)
  • 됩니다.newbranch.
  • 후, 그 이 다시 체리를 콕 집어 넣는다.newbranch브랜치에서는 더 이상 참조되지 않기 때문에 git의 reflog를 사용하여 참조합니다.HEAD@{2}의 커밋입니다.HEAD 작업 ,즉 1. 에 두 가지 .newbranch2. 아, 2. 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.git reset3월 1일, 3번으로 하다

하게 되어 (를 들면, 「 수동으로 무효로 경우, 「」를 실행한 후, 수 reflog 」 warning 예 、 「 」git reset --keep HEAD~3.

reflog에 의존하지 않는 대체 방법은 다음과 같습니다.

# newbranch will omit the 3 most recent commits.
git checkout -b newbranch HEAD~3
git branch --set-upstream-to=oldbranch
# Cherry-picks the extra commits from oldbranch.
git cherry-pick ..oldbranch
# Discards the 3 most recent commits from oldbranch.
git branch --force oldbranch oldbranch~3

(글을 됩니다)@{-1} - - 브런치 - 브런치 - 브런치 - 브런치oldbranch를 참조해 주세요.


기술적인 설명

?가왜?git rebase첫 번째 예 후에 3개의 커밋을 폐기하시겠습니까?★★★★★★★★★★★★★★★ git rebase하지 않고, 「」를 하게 합니다.--fork-point디폴트 옵션: 로컬리프로그를 사용하여 강제 리셋되는 업스트림브런치에 대한 견고성을 시도합니다.

커밋 M1, M2, M3이 포함되어 있을 때 오리진/마스터에서 분기하여 직접 3개의 커밋을 수행했다고 가정합니다.

M1--M2--M3  <-- origin/master
         \
          T1--T2--T3  <-- topic

그러나 누군가가 M2를 삭제하기 위해 오리진/마스터를 강제로 눌러 이력을 다시 씁니다.

M1--M3'  <-- origin/master
 \
  M2--M3--T1--T2--T3  <-- topic

리필로그를 하여 " " " 를 사용합니다.git rebase는, 브랜치로부터 알 수 있습니다. 및 토픽브런치의., 「」, 「」, 「」, 「M2」, 「M3」를 참조할 수 있습니다.따라서 M2가 업스트림브런치에서 삭제되었기 때문에 토픽브런치가 재베이스가 되면 토픽브런치에서도 M2가 삭제되는 것을 합리적으로 상정하고 있습니다.

M1--M3'  <-- origin/master
     \
      T1'--T2'--T3'  <-- topic (rebased)

이 동작은 타당하며 일반적으로 기본을 변경할 때 올바른 작업입니다.

따라서 다음 명령어가 실패하는 이유는 다음과 같습니다.

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

잘못된 상태로 재로그를 남겨두기 때문입니다.이 Git을 보다newbranch커밋을 에 3개의 커밋을 포함한 리비전으로 합니다.reset --hard커밋을 다음 번 시 "Commit"을 실행합니다.git rebase업스트림에서 삭제된 다른 커밋과 마찬가지로 폐기됩니다.

다만, 이 경우는, 이 3개의 커밋을 토픽 브랜치의 일부로서 고려해 주세요.그러기 위해서는 3개의 커밋을 포함하지 않는 이전 리비전의 업스트림으로 분기할 필요가 있습니다.이것이 제가 제안하는 솔루션이기 때문에 둘 다 올바른 상태로 재로그를 유지합니다.

것에 대하여는, 「」의 해 주세요.--fork-pointgit rebase git merge-base documents로 지정합니다.

또 다른 방법은 2개의 명령어를 사용하는 것입니다.또한 현재 작업 중인 트리를 그대로 유지합니다.

git checkout -b newbranch # switch to a new branch
git branch -f master HEAD~3 # make master point to some older commit

이전 버전 - 다음 정보를 알기 전에git branch -f

git checkout -b newbranch # switch to a new branch
git push . +HEAD~3:master # make master point to some older commit 

수 것push로로 합니다..알아두면 좋은 요령이야

git stash를 사용하여 훨씬 심플한 솔루션

여기 잘못된 지점에 대한 커밋을 위한 훨씬 더 간단한 해결책이 있습니다.master3번으로 나누다

git reset HEAD~3
git stash
git checkout newbranch
git stash pop

이거 언제 쓰죠?

  • master
  • 파일 변경 내용을 유지하려는 경우
  • 잘못된 커밋의 메시지는 신경 쓰지 않습니다.
  • 아직 밀지 않았구나
  • 외우기 쉬웠으면 좋겠군
  • 임시 지점/신규 지점, 커밋 해시 검색 및 복사, 기타 골칫거리 등 복잡한 작업은 원치 않습니다.

회선 번호별 기능

  1. 의 커밋 그 을 3개의 커밋으로 .master 모든 파일은 그대로
  2. 변경을 하여 " " " 를 .masterHEAD ~ 3 상 head head head head head head head head head head head head head head head 。
  3. 브랜치로 합니다.newbranch
  4. 저장된 변경 내용을 작업 디렉토리에 적용하고 저장 내용을 지웁니다.

해서 '어울리지 않다'를 할 수 되었습니다.git add ★★★★★★★★★★★★★★★★★」git commit새로운 모두 커밋에 추가됩니다.newbranch

이것이 하지 않는 일

  • 랜덤한 임시 분기가 트리를 어지럽히는 일은 없습니다.
  • 잘못된 커밋 메시지는 보존되지 않으므로 이 새로운 커밋에 새로운 커밋 메시지를 추가해야 합니다.
  • 업데이트! 위 화살표를 사용하여 명령 버퍼를 스크롤하여 커밋 메시지와 함께 이전 커밋을 다시 적용합니다(감사합니다 @ARK).

목표들

OP는 변경 사항을 잃지 않고 "이러한 커밋이 이루어지기 이전으로 되돌리는 것"을 목표로 하고 있으며, 이 솔루션은 이를 실현하고 있습니다.

는 적어도 에 한 번, 때 .masterdevelop이 를 사용합니다.git reset HEAD^1개의 커밋을 롤백하는 것이 보다 간단한 방법입니다.

마스터의 변경 내용을 업스트림으로 푸시한 경우 이 작업 안 함

다른 누군가가 그 변화를 끌어냈을 수도 있다.로컬 마스터를 다시 쓰는 경우만 업스트림으로 푸시해도 영향은 없지만 다시 작성된 이력을 공동작업자에게 푸시하면 골칫거리가 될 수 있습니다.

가장 간단한 방법:

1. 이름 바꾸기master「」에 분기하다newbranch( 하고 있는 것)master★★★★★★★★★★★★★★★★★★:

git branch -m newbranch

2. 작성master이치노

git checkout -b master <seven_char_commit_id>

예: git checkout - b 마스터 a34bc22

주의:

「」의:newbranchorigin/master.

이것은 기술적인 의미에서 그들을 '움직이는' 것은 아니지만, 같은 효과가 있습니다.

A--B--C  (branch-foo)
 \    ^-- I wanted them here!
  \
   D--E--F--G  (branch-bar)
      ^--^--^-- Opps wrong branch!

While on branch-bar:
$ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range)

A--B--C  (branch-foo)
 \
  \
   D-(E--F--G) detached
   ^-- (branch-bar)

Switch to branch-foo
$ git cherry-pick E..G

A--B--C--E'--F'--G' (branch-foo)
 \   E--F--G detached (This can be ignored)
  \ /
   D--H--I (branch-bar)

Now you won't need to worry about the detached branch because it is basically
like they are in the trash can waiting for the day it gets garbage collected.
Eventually some time in the far future it will look like:

A--B--C--E'--F'--G'--L--M--N--... (branch-foo)
 \
  \
   D--H--I--J--K--.... (branch-bar)

기록을 다시 쓰지 않고 이 작업을 수행하려면(예: 커밋을 이미 푸시한 경우)

git checkout master
git revert <commitID(s)>
git checkout -b new-branch
git cherry-pick <commitID(s)>

그러면 두 가지를 힘 없이 밀 수 있습니다!

바로 이런 상황이 있었다:

Branch one: A B C D E F     J   L M  
                       \ (Merge)
Branch two:             G I   K     N

퍼포먼스:

git branch newbranch 
git reset --hard HEAD~8 
git checkout newbranch

내가 헤드가 될 줄 알았는데 L을 약속하면...

역사의 적소에 확실히 착지하려면 , 커밋의 해시에 의해서 작업하기 쉬워집니다.

git branch newbranch 
git reset --hard #########
git checkout newbranch

이거 어떻게 해야 돼?

A - B - C - D - E 
                |
                master

이거에 대해서요?

A - B - C - D - E 
    |           |
    master      newbranch

2개의 명령어로

  • git branch - master new branch

부여

A - B - C - D - E 
                |
                newbranch

그리고.

  • git 브랜치마스터 B

부여

A - B - C - D - E
    |           |
    master      newbranch

TLDR

git checkout branch_to_remove_commits
git reset --hard ${hash_of_new_tip}
git checkout -b branch_to_store_commits
# Move commits (single hash, list of hashes or range ffaa..ffoo) 
git cherry-pick ${commit_hash}
git push --set-upstream origin branch_to_store_commits
# Switch back to last branch
git checkout -
git push -f

나를 위해.

git log --pretty=oneline -n ${NUMBER}

는 문제의 커밋해시를 식별하는데 가장 적합합니다.

모든 미해결 커밋을 새 지점으로 이동시켜야 한다면, 그땐 그냥

  1. 현재 브런치에서 새로운 브런치를 만듭니다.git branch new-branch-name

  2. 새로운 브랜치를 푸시합니다.git push origin new-branch-name

  3. 이전(현재) 분기를 마지막 푸시/삭제 상태로 되돌립니다.git reset --hard origin/old-branch-name

은 또한 것을 있다.upstreamsorigin, 적절한 것을 .upstream

이 작업은 제가 사용한 간단한 3단계입니다.

1) 최신 업데이트를 커밋하는 새로운 브랜치를 만듭니다.

git branch <branch name>

2) 새로운 브랜치에서의 커밋의 최근 커밋 ID를 검색합니다.

git log

3) 가장 최근의 커밋 리스트가 맨 위에 있는 커밋 ID 노트를 복사합니다.헌신을 찾을 수 있습니다.메시지를 통해서도 찾을 수 있습니다.

git cherry-pick d34bcef232f6c...

커밋 ID의 링도 지정할 수 있습니다.

git cherry-pick d34bcef...86d2aec

이제 네 일은 끝났어.올바른 ID와 올바른 분기를 선택했다면 성공입니다.그러니까 이거 하기 전에 조심해요.그렇지 않으면 다른 문제가 발생할 수 있습니다.

이제 코드를 푸시할 수 있습니다.

git push

아무도 이 방법을 추천하지 않아 놀랐습니다.

git checkout master
git checkout <commit hash from which you want to split>
git checkout -b new_branch
git rebase master
git checkout master
git reset --hard <commit hash you splitted>

설명:

  1. 스텝 분할할 커밋을 체크합니다.
  2. 이 커밋에서 새로운 브랜치를 만듭니다.
  3. rebase를 실행하면 new_displaces와 마스터가 동기화됩니다.이제 같은 커밋을 가진 두 개의 같은 지점이 있습니다.
  4. 마스터로 리셋하면 분할 후 마지막 커밋을 정리합니다.
  5. 목록 항목

1) 새로운 브런치를 만들고 모든 변경을 new_branch로 이동합니다.

git checkout -b new_branch

2) 이전 브랜치로 돌아갑니다.

git checkout master

3) git rebase를 실행하다

git rebase -i <short-hash-of-B-commit>

4) 열려 있는 에디터에는 마지막 3개의 커밋 정보가 포함되어 있습니다.

...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...

) 변경 5) ★★pick로로 합니다.drop3시입니다.그런 다음 편집기를 저장하고 닫습니다.

...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...

됩니다(6).master 이번에는 +이치노

git push origin +master

이 솔루션의 대부분은 되돌아가고 싶은 커밋의 양을 세고 있습니다.이것은 오류가 발생하기 쉬운 방법론이라고 생각합니다.세는 건 재검표가 필요할 거야

HEAD에서 하고 싶은 커밋의 커밋 해시를 전달하거나 다른 말로 마지막 커밋이 되고 싶은 커밋 해시를 전달하거나 할 수 있습니다.

(커밋 해시 참조)

이를 피하기 위해:

1) git checkout master

2) git branch <feature branch> master

3) git reset --hard <commit hash>

4) git push -f origin master

Magit을하면 Emacs Git Magit을 누르면 이 할 수 .b s (magit-hit-spinoff)새 지점의 이름을 입력하라는 메시지가 표시되고 Enter 키를 누르면 voila가 표시됩니다.

Magit 문서:

이 명령어는 에서 시작하여 현재 브랜치를 추적하는 새로운 브랜치를 만들고 체크아웃합니다.다음으로 그 브랜치는 업스트림과 공유하는 마지막 커밋으로 리셋됩니다.현재 브랜치에 업스트림커밋이 없거나 푸시되지 않은 커밋이 없는 경우 새 브랜치가 생성되고 이전에 브랜치가 터치되지 않습니다.

이 기능은 이전 분기(마스터와 비슷하지만 반드시 "마스터"일 필요는 없음)에서 작업이 이미 시작된 후 기능 분기를 만드는 데 유용합니다.

7개의 커밋을 하나의 오래된 지점에서 새로운 지점으로 옮겨야 합니다.

git checkout old-branch     # in the example, master
git reset --hard h4sh       # h4sh is the hash for the commit 
git checkout -b new-branch  
git push origin new-branch

그 후 두 브랜치는 모두 제가 한 7개의 커밋에 관련된 것입니다.★★★ git checkout new-branch해 지고 있었습니다.git log ★★★★★★★★★★★★★★★★★」git status(오래된 old-timeout)에 git checkout old-branch7 be 라는 git is be 7 commits and can be fast-forward" 。가 이 것은 과 같은내용이었다.

git checkout old-branch
git status 
> git is behind by 7 commits and can be fast-forwarded
git push origin old-branch -f

그 후 마지막 7개의 커밋은 new-branch에만 참조되며 이전 커밋은 bitbucket 트리의 old-branch 및 new-branch로 참조됩니다.

저 같은 UI 사용자이고 Visual Studio를 사용하고 있다면.다음으로 다음 작업을 수행할 수 있습니다.저 같은 경우에는 최신 커밋을 다른 지점에 맡기고 싶습니다.

  1. 앞의 것을 오른쪽 클릭합니다(커밋).

여기에 이미지 설명 입력

  1. 따라서 모든 커밋 변경이 [Git Changes]페인에 표시됩니다.

  2. 이제 변경 내용을 저장합니다.

여기에 이미지 설명 입력

  1. 대상 브랜치로 이동하거나 오른쪽 아래 모서리에서 새 브랜치를 만듭니다.

여기에 이미지 설명 입력

  1. "Git Changes"에서 최신 Stash를 두 번 클릭합니다.

  2. "상세 저장" 창이 열립니다."팝"을 클릭한 다음 충돌을 해결합니다(있는 경우).

여기에 이미지 설명 입력

  1. 마지막으로 변경을 커밋합니다.

3개의 커밋의 영향을 받는 파일을 Staged로 되돌린 후 새로운 브랜치에 코드를 다시 커밋할 수 있습니다.하고 있다고 가정하면master을 3개의 커밋으로 .new-branch:

  • git reset --soft HEAD~3
  • git checkout -b new-branch
  • git commit -m "message"

에서 이 해시를 .new-branch기타 답변에 의해 강조되는 향후 기본 변경은 피할 수 있습니다.경합을 를 .master:

  • git checkout master
  • git push -ff

또한 이 솔루션은 커밋을 완전히 다시 작성할 수 있는 유연성을 제공합니다.위의 예에서는 3개의 커밋을 1개의 커밋으로 대체합니다. 「」, 「」를 으로, 할 수 .commit에는 다음과 같이 입력합니다.- 음음 、 음음 、 。

  • git reset 파일 모든 파일 삭제)
  • git add path/file_1
  • git commit -m "first-commit"
  • git add path/file_2
  • git commit -m "second-commit"
  • ...

다른 투고에서 아이디어를 얻어 리셋을 회피하고 극도로 편집증적인 모습을 보이는 저의 솔루션은 다음과 같습니다.

  1. git branch # 변경은 새로운 브랜치에서 이용할 수 있습니다.
  2. git push # upload, 예를 들어 git push --set-push https:///와 같이 "--set-push"를 조작해야 할 수 있습니다.
  3. GUI를 통해 새로운 브랜치가 git에 있는지 확인합니다.
  4. 현재의 디렉토리를 파기하다
  5. git 저장소에서 다시 복제

자랑스럽지는 않지만 데이터는 보관하고 있습니다.

언급URL : https://stackoverflow.com/questions/1628563/move-the-most-recent-commits-to-a-new-branch-with-git

반응형