잘못된 Git 브랜치에 커밋을 수정하는 방법?


621

방금 잘못된 지점에 완벽하게 최선을 다했습니다. 마스터 브랜치에서 마지막 커밋을 취소 한 다음 동일한 변경 사항을 적용하여 업그레이드 브랜치로 가져 오려면 어떻게해야합니까?

답변:


975

변경 사항을 아직 푸시하지 않은 경우 소프트 리셋을 수행 할 수도 있습니다.

git reset --soft HEAD^

커밋을 되돌 리지만 커밋 된 변경 사항을 다시 인덱스에 넣습니다. 브랜치가 서로에 대해 상대적으로 최신 상태라고 가정하면 git은 다른 브랜치로 체크 아웃 할 수있게하면 간단하게 커밋 할 수 있습니다.

git checkout branch
git commit

단점은 커밋 메시지를 다시 입력해야한다는 것입니다.


10
소프트 리셋을 통해 변경 사항을 준비하고 커밋 할 수 있습니다. IDE가 소프트 리셋 후 파일이 수정 된 상태로 돌아 오는 것을 보여주지 않을 때 약간 혼란 스러웠습니다.
mtjhax

9
완벽한 수정, 실제로 몇 가지 커밋이 있었으므로 HEAD도 마찬가지
pablo

8
감사. 이것은 나를 두 번 구했다. 분기가 다소 다른 경우 재설정 후 및 체크 아웃 전에 다른 분기를 체크 아웃하기 전에 변경 사항을 숨겨야 할 수도 있습니다. 체크 아웃 후 숨김을 다시 적용
Kirby

17
: zsh을 사용자 : 당신은 당신이 같은 ^ 누출되어 필요 찾을 수 있습니다git reset --soft HEAD\^
스티븐 Fuhry

54
더 얻을 경우? git reset --soft "HEAD ^"
Nate Cook

140

이 주제에 대해 4 년이 늦었지만 이것은 누군가에게 도움이 될 수 있습니다.

마스터에서 커밋하고 모두 커밋하기 전에 새 브랜치를 생성하지 않은 경우 커밋 수에 관계없이 다음 방법이 더 쉽습니다.

git stash                       # skip if all changes are committed
git branch my_feature
git reset --hard origin/master
git checkout my_feature
git stash pop                   # skip if all changes were committed

이제 마스터 브랜치가 같고 origin/master모든 새로운 커밋이 켜져 my_feature있습니다. 참고 my_feature로컬 지점이 아닌 원격 하나입니다.


답변 해주셔서 감사합니다. 이제 egit을 사용하고 있으며 다음을 수행하여 동일한 작업을 수행 할 수 있는지 궁금합니다. 1) 현재 '마스터'의 이름을 'my_feature'로 바꿉니다. 2) 'origin / master'에서 로컬 'master'를 다시 만듭니다. 나는 이러한 작업을 위해
egit

왜 합병? 분기를 직접 master만든 다음로 재설정 master할 수 origin/master있습니다.
caesarsol

1
그것은 가장 흥미로운 부분입니다 : origin/master이미 커밋하고있는 커밋에 여러 커밋이 필요하지 않습니다 ! : 팁을위한 신용 그러나이 페이지입니다 github.com/blog/...
caesarsol

4
이것은 정답입니다. 간단하고 명백하며 간단하며 커밋 수에 관계없이 기본 Git 기능 만 사용합니다. TortoiseGit으로 이러한 단계를 수행했습니다. 감사! :)
Ian Grainger

1
나는 이것이 최선의 대답이라고 생각했지만 한계가 있습니다. 최근에 리모컨에서 뽑은 경우에만 도움이됩니다. 그리고 그것은 당신이 시작할 리모컨이 있다고 가정합니다. 로컬 브랜치 "master"와 새로운 기능 수정 만있는 경우 정답은 마스터가 특정 커밋 수를 다시 계산할 때 다시 설정하는 것입니다.
pauljohn32

111

깨끗한 (수정되지 않은) 작업 사본이있는 경우

한 커밋을 롤백하려면 다음 단계에 대한 커밋 해시를 확인하십시오.

git reset --hard HEAD^

커밋을 다른 브랜치로 가져 오려면 :

git checkout other-branch
git cherry-pick COMMIT-HASH

변경 사항을 수정했거나 추적하지 않은 경우

또한주의 git reset --hard어떤 비 추적 및 수정 변경 죽일 당신이 그있는 경우에 그래서 당신이 선호 할 수도, 당신이있을 수 있습니다를 :

git reset HEAD^
git checkout .

git rev-parse BRANCH_NAME샤를 얻을 수 있습니다.
wilhelmtell

12
해시를 먼저 기억하지 않으면 git reflog show <branch>!
Cascabel

2
@Jefromi 나는 잠시 동안 거기에서 두려웠다.
Ian Hunter

13
보다 안전한 느낌을 얻으려면 먼저 올바른 지점에서 체리 픽을 선택한 다음 잘못된 지점 만 재설정하십시오.
Age Mooij

1
또한 추적되지 않은 변경 사항이있는 경우 git stash재설정하기 전에 재설정하고 git stash pop나중에 복원 할 수 있으므로 --hard부품을 두려워 할 필요가 없습니다.
Clemens Klein-Robbenhaar

20

변경 사항을 이미 푸시 한 경우 HEAD를 재설정 한 후 다음 푸시를 강제 실행해야합니다.

git reset --hard HEAD^
git merge COMMIT_SHA1
git push --force

경고 : 강제 재설정은 원격 브랜치의 상태를 로컬 브랜치의 현재 상태로 완전히 덮어 쓰는 반면 하드 리셋은 작업 복사본에서 커밋되지 않은 수정 사항을 취소합니다.

Windows의 경우 (Bash가 아닌 Windows 명령 줄 사용) 실제로 ^^^^는 1이 아닌 4가 되므로

git reset --hard HEAD^^^^

6
꼭 필요한 경우가 아니면 다른 사람들이 사용하고있는 지점으로 강제 푸시 해서는 안됩니다 . 그러나 git을 사용하는 유일한 개발자라면 괜찮습니다.
블레어 홀로 웨이

2
또는 다른 사람이 잘못된 커밋을 가져 오기 전에 충분히 빨리 인식하지 않는 한.
Michael Mior

둘 이상의 커밋이 해제 된 경우 필요한 커밋을 지정할 수 있습니다. git reset --hard COMMIT_HASH git push --force
David Cramblett

17

나는 최근에 다른 지점에 헌신해야했을 때 실수로 마스터로 변경을 저지른 동일한 작업을 수행했습니다. 그러나 나는 아무것도 밀지 않았다.

방금 잘못된 지점에 최선을 다하고 그 이후로 아무것도 변경하지 않았고 repo로 푸시하지 않은 경우 다음을 수행 할 수 있습니다.

// rewind master to point to the commit just before your most recent commit.
// this takes all changes in your most recent commit, and turns them into unstaged changes. 
git reset HEAD~1 

// temporarily save your unstaged changes as a commit that's not attached to any branch using git stash
// all temporary commits created with git stash are put into a stack of temporary commits.
git stash

// create other-branch (if the other branch doesn't already exist)
git branch other-branch

// checkout the other branch you should have committed to.
git checkout other-branch

// take the temporary commit you created, and apply all of those changes to the new branch. 
//This also deletes the temporary commit from the stack of temp commits.
git stash pop

// add the changes you want with git add...

// re-commit your changes onto other-branch
git commit -m "some message..."

참고 : 위 예제에서 git reset HEAD ~ 1로 1 commit을 되 감았습니다. 그러나 n 커밋을 되 감고 싶다면 git reset HEAD ~ n을 수행 할 수 있습니다.

또한 잘못된 분기에 커밋하고 잘못된 분기에 커밋했다는 것을 깨닫기 전에 코드를 더 작성하면 git stash를 사용하여 진행중인 작업을 저장할 수 있습니다.

// save the not-ready-to-commit work you're in the middle of
git stash 

// rewind n commits
git reset HEAD~n 

// stash the committed changes as a single temp commit onto the stack. 
git stash 

// create other-branch (if it doesn't already exist)
git branch other-branch

// checkout the other branch you should have committed to.
git checkout other-branch

// apply all the committed changes to the new branch
git stash pop

// add the changes you want with git add...

// re-commit your changes onto the new branch as a single commit.
git commit -m "some message..."

// pop the changes you were in the middle of and continue coding
git stash pop

참고 : 나는이 웹 사이트를 참조 https://www.clearvision-cm.com/blog/what-to-do-when-you-commit-to-the-wrong-git-branch/


비슷한 일이 일어 났고, 나는 마스터에서 몇 가지 변화를 저질렀지만 새로운 지점에서 PR을 보내야했는데, git checkout -b new_branch바로 거기에서 바로 일을하고 커밋은 그대로하고 밀어 넣고 PR을 만들었습니다. ' 다시 커밋하지 않아도됩니다.
Nishchal Gautam

11

따라서 시나리오가 master커밋했지만 커밋하려는 의도 another-branch(아직 존재하지 않을 수도 있음)이지만 아직 푸시하지 않은 경우 쉽게 해결할 수 있습니다.

// if your branch doesn't exist, then add the -b argument 
git checkout -b another-branch
git branch --force master origin/master

이제 모든 커밋이 시작 master됩니다 another-branch.

http://haacked.com/archive/2015/06/29/git-migrate/ 에서 사랑으로 공급


가장 간단한 접근법 인 것 같습니다! 왜 그렇게 작은 사랑과 멍청이인지 확실하지 않습니다
keligijus

4
이것은 나를 위해 작동하지 않는 것 같습니다. another-branch이미 존재합니다. 이 경우, 내가 마스터 한 커밋을 마비시키고 넣지 않았습니다 another-branch.
Giselle Serate

6

예 를 들어 다음 과 같이 여러 커밋 이 필요한 경우이 답변 을 자세히 설명하십시오 .developnew_branch

git checkout develop # You're probably there already
git reflog # Find LAST_GOOD, FIRST_NEW, LAST_NEW hashes
git checkout new_branch
git cherry-pick FIRST_NEW^..LAST_NEW # ^.. includes FIRST_NEW
git reflog # Confirm that your commits are safely home in their new branch!
git checkout develop
git reset --hard LAST_GOOD # develop is now back where it started

1
나는 세 번의 커밋을 되돌려 놓았는데,이 질문은 내 엉덩이를 불에서 끌어 낸 것으로 보인다. 감사!
holdenweb

3

이 문제가 발생하고 Visual Studio가있는 경우 다음을 수행 할 수 있습니다.

지점을 마우스 오른쪽 버튼으로 클릭하고 다음을 선택하십시오 View History.

여기에 이미지 설명을 입력하십시오

돌아 가려는 커밋을 마우스 오른쪽 버튼으로 클릭하십시오. 그리고 필요에 따라 되돌리기 또는 재설정하십시오.

여기에 이미지 설명을 입력하십시오


3

잘못된 브랜치에서 여러 커밋

당신을 위해, 그것은 약 1 커밋이라면, 다른 더 쉬운 재설정 솔루션을 사용할 수 있습니다. 나를 위해, 나는 실수로 master대신 약 10 개의 커밋을 했다 branch_xyz.

당신이 할 수 있고, 저를 구한 것은 4 단계 프로세스를 사용 하여이 답변 을 참조로 사용했습니다.

  1. 에서 새 임시 분기를 만듭니다. master
  2. 원래 커밋을위한 브랜치로 병합 branch_xyz
  3. 커밋 실행 취소 master
  4. 임시 분기를 삭제하십시오.

위의 단계는 다음과 같습니다.

  1. master(실수로 많은 변경을 저지른 곳 에서) 새 지점을 만듭니다.

    git checkout -b temp_branch_xyz
    

    참고 : -b플래그는 새 분기를 만드는 데 사용됩니다.
    이 권리를 가지고 git branch있는지 확인하기 위해 temp_branch_xyz지점 git log에 있는지 확인하고 커밋 이 올바른지 확인하기 위해 빨리 할 것 입니다.

  2. 임시 분기를 원래 커밋을위한 분기로 병합합니다 (예 :) branch_xyz.
    먼저 원래 지점으로 전환하십시오 branch_xyz( 예 : git fetch그렇지 않은 경우 필요할 수 있음)

    git checkout branch_xyz
    

    참고 : -b플래그를 사용하지 않습니다.
    이제 임시 지점을 현재 체크 아웃 한 지점으로 병합합니다branch_xyz

    git merge temp_branch_xyz
    

    충돌이있을 경우 여기에서 약간의 충돌을 처리해야 할 수도 있습니다. 성공적으로 병합 한 후 다음 단계로 넘어갈 수 있습니다.

  3. 이 답변 을 참조로 master사용하여 실수로 커밋을 취소하고 먼저master

    git checkout master
    

    그런 다음 리모컨 (또는 원하는 경우 특정 커밋)과 일치하도록 완전히 되돌립니다.

    git reset --hard origin/master
    

    다시 한 번, git log의도 한 변경 사항이 적용되도록하기 위해 전후에 노력 하겠습니다 .

  4. 증거를 지우면 임시 분기가 삭제됩니다. 이를 위해 먼저 temp가 병합 된 분기를 체크 아웃해야합니다 branch_xyz( 즉 master, 아래 명령 을 계속 실행하면을 얻을 수 있음 error: The branch 'temp_branch_xyz' is not fully merged).

    git checkout branch_xyz
    

    이 사고의 증거를 삭제하십시오.

    git branch -d temp_branch_xyz
    

당신은 간다.


1

변경 사항을 적용하려는 지점이 이미 존재하는 경우 ( 예 : 지점 개발 ) 아래 fotanus 에서 제공 한 지침을 따르십시오 .

git checkout develop
git rebase develop my_feature # applies changes to correct branch
git checkout develop # 'cuz rebasing will leave you on my_feature
git merge develop my_feature # will be a fast-forward
git branch -d my_feature

그리고 원하는 경우 my_feature 대신 tempbranch 또는 다른 분기 이름을 사용할 수 있습니다 .

또한 해당되는 경우 대상 분기에서 병합 할 때까지 숨김 팝 (적용)을 지연시킵니다.


첫 번째 명령 (체크 아웃 개발)은 불필요하다고 생각합니다. rebase는 "my_feature"를 첫 번째로 체크 아웃합니다.
JoelFan

또한 "rebase"명령의 "my_feature"매개 변수를 생략 할 수 있습니다 (이미 "my_feature"를 체크 아웃 했으므로). "병합"의 "develop"매개 변수를 생략 할 수도 있습니다 (이미 "develop"를 체크 아웃
했으므로

1

나를 위해, 이것은 내가 저지른 커밋을 되 돌린 다음 다른 지점으로 커밋을 체리 피킹하여 해결되었습니다.

git checkout branch_that_had_the_commit_originally
git revert COMMIT-HASH
git checkout branch_that_was_supposed_to_have_the_commit
git cherry pick COMMIT-HASH

git log올바른 해시를 찾는 데 사용할 수 있으며 원할 때마다 이러한 변경 사항을 푸시 할 수 있습니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.