git reset –soft의 실제 사용? 이해 git commit –amend합니다. 이 두

나는 한 달 이상 git과 함께 일 해왔다. 실제로 어제 처음으로 리셋을 사용했지만 소프트 리셋은 여전히 ​​나에게 의미가 없습니다.

소프트 리셋을 사용하여 인덱스 또는 작업 디렉토리를 변경하지 않고 커밋을 편집 할 수 있음을 이해 git commit --amend합니다.

이 두 명령이 실제로 동일 합니까 ( reset --softvs commit --amend)? 실용적인 용어로 하나를 사용해야하는 이유는 무엇입니까? 더 중요한 것은 reset --soft커밋을 수정하는 것 외에 다른 용도 가 있습니까?



답변

git reset이동 HEAD에 관한 것이며, 일반적으로 분기 참조 입니다.
질문 : 워킹 트리와 인덱스는 어떻습니까?
함께 사용하면 --soft, 이동 HEAD, 가장 자주 분기 심판 업데이트 만HEAD .
이것은 다음과 다릅니다 commit --amend.

  • 새로운 커밋을 만들지 않습니다.
  • 실제로 HEAD를 모든 커밋으로 옮길 수 있습니다 ( 현재 커밋을 다시 실행하면서 HEAD를 움직이지 않는 것과 관련 commit --amend이 있습니다 )

이 결합 예제를 찾았습니다.

  • 고전적인 합병
  • 서브 트리 병합

커밋 병합은 모두 하나로 통합됩니다 (두 개 이상의 브랜치가 병합되어 있기 때문에 문어).

Tomas “wereHamster”Carnecky“Subtree Octopus merge”기사 에서 다음과 같이 설명합니다 .

  • 하나의 프로젝트를 다른 프로젝트의 서브 디렉토리에 병합 한 후 서브 프로젝트를 최신 상태로 유지하려는 경우 서브 트리 병합 전략을 사용할 수 있습니다. git 서브 모듈의 대안입니다.
  • 문어 병합 전략을 사용하여 세 개 이상의 분기를 병합 할 수 있습니다. 일반적인 전략은 두 개의 브랜치 만 병합 할 수 있으며 그보다 더 많이 병합하려고하면 git은 자동으로 낙지 전략으로 넘어갑니다.

문제는 하나의 전략 만 선택할 수 있다는 것입니다. 그러나 전체 저장소가 원자 적으로 새로운 버전으로 업데이트되는 깨끗한 기록을 얻기 위해 두 가지를 결합하고 싶었습니다.

나는 슈퍼 projectA프로젝트, 그것을 호출 하고 서브 프로젝트를 가지고 있는데 projectB, 나는 서브 디렉토리에 병합했다 projectA.

(하위 트리 병합 부분입니다)

또한 몇 가지 로컬 커밋을 유지하고 있습니다.
ProjectA정기적으로 업데이트되며 projectB며칠 또는 몇 주마다 새 버전이 있으며 일반적으로의 특정 버전에 따라 다릅니다 projectA.

나는 두 프로젝트를 업데이트하기로 결정했을 때, 나는 단지에서 잡아 당기지 마십시오 projectAprojectB 그로 전체 프로젝트의 원자 갱신해야 무엇을위한 두 개의 커밋을 만들 것입니다 .
대신에, 나는 하나의 병합하는 콤바인 커밋 만들고 projectA, projectB내 지역 커밋 .
여기서 까다로운 부분은 이것이 문어 병합 (세 개의 머리) 이지만 projectB하위 트리 전략과 병합되어야한다는 것 입니다. 그래서 이것이 내가하는 일입니다.

# Merge projectA with the default strategy:
git merge projectA/master

# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master

여기에 저자는 사용 reset --hardread-tree처음 두 병합은 작업 트리와 인덱스에 한 일을 복원하지 않고 곳입니다 reset --soft도움이 될 수 있습니다
나는 그 두 병합 다시 실행하는 방법을 일했다, 즉, 내 작업 트리와 인덱스입니다 괜찮지 만 그 두 커밋을 기록하지 않아도됩니까?

# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}

이제 Tomas의 솔루션을 다시 시작할 수 있습니다.

# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD

# And finally do the commit:
git commit

따라서 매번 :

  • 당신은 당신이 끝내는 것에 만족합니다 (작업 트리 및 색인 측면에서)
  • 당신은 거기에 도착한 모든 커밋에 만족 하지 않습니다 .

git reset --soft 답입니다.


답변

유스 케이스-일련의 로컬 커밋 결합

“죄송합니다.이 세 가지 커밋은 하나 일 수 있습니다.”

따라서 마지막 3 개 (또는 무엇이든) 커밋을 취소하십시오 (색인이나 작업 디렉토리에 영향을 미치지 않고). 그런 다음 모든 변경 사항을 하나로 커밋하십시오.

예 :

> git add -A; git commit -m "Start here."
> git add -A; git commit -m "One"
> git add -A; git commit -m "Two"
> git add -A' git commit -m "Three"
> git log --oneline --graph -4 --decorate

> * da883dc (HEAD, master) Three
> * 92d3eb7 Two
> * c6e82d3 One
> * e1e8042 Start here.

> git reset --soft HEAD~3
> git log --oneline --graph -1 --decorate

> * e1e8042 Start here.

이제 모든 변경 사항이 유지되고 하나로 커밋 할 수 있습니다.

질문에 대한 짧은 답변

이 두 명령이 실제로 동일 합니까 ( reset --softvs commit --amend)?

  • 아니.

실용적인 용어로 하나를 사용해야하는 이유는 무엇입니까?

  • commit --amend 가장 최근의 커밋에서 파일을 추가하거나 메시지를 변경합니다.
  • reset --soft <commit> 여러 순차 커밋을 새로운 커밋으로 결합합니다.

더 중요한 것은 reset --soft커밋을 수정하는 것 외에 다른 용도 가 있습니까?

  • 다른 답변보기 🙂

답변

나는 그것을 마지막 커밋 보다 더 수정하기 위해 사용합니다 .

커밋 A에서 실수를 한 다음 커밋 B를 만들었다 고 가정 해 봅시다. 이제 B 만 수정할 수 있습니다. 따라서 git reset --soft HEAD^^A를 수정하고 다시 커밋 한 다음 B를 다시 커밋합니다.

물론, 그것은 큰 커밋에 매우 편리하지는 않지만 어쨌든 큰 커밋을해서는 안됩니다 😉


답변

또 다른 잠재적 인 사용은 숨김에 대한 대안입니다 (일부 사람들이 싫어하는 예 : https://codingkilledthecat.wordpress.com/2012/04/27/git-stash-pop-considered-harmful/ 참조 ).

예를 들어, 지점에서 작업 중이고 마스터에서 긴급하게 무언가를 수정해야하는 경우 다음을 수행 할 수 있습니다.

git commit -am "In progress."

그런 다음 마스터를 확인하고 수정하십시오. 완료되면 지점으로 돌아가서

git reset --soft HEAD~1

내가 그만 둔 곳에서 계속 일하기 위해서


답변

git reset --soft인덱스 및 작업 트리에서 변경 한 내용의 부모로 사용하려는 버전을 변경하는 데 사용할 수 있습니다 . 이것이 유용한 경우는 드 rare니다. 때로는 작업 트리에서 변경 한 내용이 다른 브랜치에 속해야한다고 결정할 수도 있습니다. 또는 이것을 여러 커밋을 하나로 축소하는 간단한 방법으로 사용할 수 있습니다 (스쿼시 / 접기와 유사).

실용적인 예는 VonC의이 답변을 참조하십시오.
Git에서 처음 두 커밋을 스쿼시 하시겠습니까?


답변

다른 컴퓨터에서 작업을 계속하려는 경우 한 가지 가능한 사용법이 있습니다. 다음과 같이 작동합니다.

  1. 숨김 같은 이름으로 새 지점을 체크 아웃하십시오.

    git checkout -b <branchname>_stash
    
  2. 은신처를 밀어 올리십시오.

    git push -u origin <branchname>_stash
    
  3. 다른 기계로 전환하십시오.

  4. 줄기와 기존 가지를 모두 아래로 당깁니다.

    git checkout <branchname>_stash; git checkout <branchname>
    
  5. 기존 지사에 있어야합니다. 숨김 지점에서 변경 사항을 병합하고

    git merge <branchname>_stash
    
  6. 병합하기 전에 기존 지점을 1로 소프트 재설정

    git reset --soft HEAD^
    
  7. 숨김 분기를 제거하고

    git branch -d <branchname>_stash
    
  8. 또한 스 태쉬 브랜치를 원점에서 제거하십시오.

    git push origin :<branchname>_stash
    
  9. 변경 사항을 정상적으로 보관 한 것처럼 계속 작업하십시오.

나는 미래에 GitHub와 공동으로 생각합니다. 이 “원격 숨김”기능을 더 적은 단계로 제공해야합니다.


답변

한 가지 실용적인 용도는 로컬 리포지토리에 이미 커밋 한 경우 (예 : git commit -m) git reset –soft HEAD ~ 1 을 수행하여 마지막 커밋을 되돌릴 수 있습니다.

또한 지식에 대한, 다음을 수행하여 준비를 취소 할 수 있습니다. (즉, 자식 추가로) 이미 변경 사항을 개최 당신이 경우 자식 재설정을 HEAD를 –mixed 또는 내가 일반적으로도 바로 사용했습니다git reset

마지막으로, git reset –hard는 로컬 변경을 포함하여 모든 것을 지 웁니다 . ~ after head는 상단에서 몇 개의 커밋을하는지 알려줍니다.