IT박스

Mercurial에서 커밋을 스쿼시 할 수 있습니까?

itboxs 2020. 8. 12. 07:59
반응형

Mercurial에서 커밋을 스쿼시 할 수 있습니까?


정말 하나 여야하는 커밋 쌍이 있습니다. git을 사용하는 경우 다음을 사용합니다.

git rebase -i <some-commit-before>

스쿼시합니다.

수은으로 할 수 있습니까? 그렇다면 어떻게?


예, Concatenating Changesets를 통해 확장없이 mercurial을 사용하여이 작업을 수행 할 수 있습니다 .

또는 확장을 사용하려면 다음을 사용할 수 있습니다.


내가 가장 좋아하는 것은 hg strip --keep명령입니다. 그런 다음 하나의 커밋으로 모든 변경 사항을 커밋합니다.

매일 작업하는 동안 작은 커밋을 많이하는 것을 좋아하기 때문에 가장 빠르고 편안한 방법입니다.)


참고 1 : 사용 strip하려면 기본 제공 확장 mq필요합니다 .
주 2 : 내 마음에 드는 힘내 /만으로는 클라이언트 (SmartGit / 수은)이 기본으로 추가 --keep하는 동안 매개 변수 strip. 그리고 더 편리한 것은 join commits:] 라는 옵션을 제공합니다 .


Rebase 현재 확장은 마치 마법처럼 일했다. 2 개의 커밋을 스쿼시하려면 :

$ hg rebase --dest .~2 --base . --collapse

Dot은 현재 개정판의 바로 가기입니다.

브랜치에 커밋이 몇 개 있고 모두 하나로 축소하려는 경우 훨씬 더 쉽습니다.

$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse

작동 원리 :

여기에 이미지 설명 입력

( http://mercurial-scm.org/wiki/RebaseExtension#Collapsing에서 )


이 답변을 읽고 있다면이 답변에 언급 된 다른 모든 옵션을 잊어 버리고 evolve 확장fold명령을 사용할 수 있습니다 .

evolve안전한 변이 역사를 갖는 데 도움이되는 수은의 연장선이지만 여전히 실험적입니다. 저장소 에서 복제 하여 .hgrc에 추가하여 사용할 수 있습니다 .

[extensions]
evolve = ~/evolve/hgext/evolve.py

홈 디렉토리에서 evolve repo를 복제했다고 가정합니다. 이제 갈 수 있습니다. 을 통해 도움을받을 수도 있습니다 hg help fold.

접기 명령

당신은 말할 fold/ 스쿼시에 파괴되지 않은 커밋의 선형 체인을 접습니다. fold가하는 일은 모든 변경 세트의 변경 사항을 포함하는 새로운 변경 세트를 생성하고 모든 커밋을 쓸모없는 것으로 표시하는 것입니다. docs 에서 이것에 대해 더 자세히 볼 수 있습니다 .

이제 다음과 같은 역사가 있다고 가정합니다.

a -> b -> c -> d -> e -> f -> g

스쿼시 e, fg. 넌 할 수있어

hg up g
hg fold -r e

결과는

a -> b -> c -> d -> h

여기서 h모든 세 개의 커밋에서 변경된 사항을 담고 변경 집합이다 e, f하고 g.

히스토리 중간에서 변경 세트를 접을 수도 있습니다. 즉, 팁이 포함 된 체인을 선택하지 않아도됩니다. 폴드한다고 가정 b, cd. 넌 할 수있어

hg up d
hg fold -r b
hg evolve --all

결과적으로

a -> i -> j

여기서 i의 절첩 변경 집합이고 b, c, dj같은 변경 집합이다 h. Evolve 사용자 가이드 는 반드시 읽어야합니다.


Mercurial 4.8 (2018 년 11 월, 9 년 후)을 사용하면 새로운 명령을 고려할 수 있습니다 (이전hg aborb 에는 실험적인 기능 이었습니다 ).

자세한 내용은 " 의욕 4.8의 변경 사항을 커밋 흡수 "

The absorb extension will take each change in your working directory, figure out which commits in your series modified that line, and automatically amend the change to that commit.
If there is any ambiguity (i.e multiple commits modified the same line), then absorb will simply ignore that change and leave it in your working directory to be resolved manually.

At a technical level, hg absorb finds all uncommitted changes and attempts to map each changed line to an unambiguous prior commit.
For every change that can be mapped cleanly, the uncommitted changes are absorbed into the appropriate prior commit. Commits impacted by the operation are rebased automatically.
If a change cannot be mapped to an unambiguous prior commit, it is left uncommitted and users can fall back to an existing workflow (e.g. using hg histedit).

The automatic rewriting logic of hg absorb is implemented by following the history of lines: This is fundamentally different from the approach taken by hg histedit or git rebase, which tend to rely on merge strategies based on the 3-way merge to derive a new version of a file given multiple input versions.

This approach combined with the fact that hg absorb skips over changes with an ambiguous application commit means that hg absorb will never encounter merge conflicts!

Now, you may be thinking if you ignore lines with ambiguous application targets, the patch would always apply cleanly using a classical 3-way merge. This statement logically sounds correct. But it isn't: hg absorb can avoid merge conflicts when the merging performed by hg histedit or git rebase -i would fail.


I think chistedit (built in since Mercurial 2.3) is the closest to rebase -i that is pure Mercurial (chistedit is the interactive version of histedit). Once in histedit the fold command maps to rebase's squash and roll command maps to rebase's fixup. See histedit docs for more info.

Here is a simple example. Assume you have the following and want to move all 1e21c4b1's changes into the previous revision and just keeping the previous revision's message.

@  1e21c4b1 drees tip
|  A commit you want to squash
o  b4a738a4 drees
|  A commit
o  788aa028 drees
|  Older stuff

You can run hg chistedit -r b4a738a4 to edit history back to b4a738a4. In chistedit you then cursor down to 1e21c4b1 and hit r to indicate you want to roll that revision. Do note that the order in histedit (oldest to newest) is reversed from hg log (newest to oldest).

#0  pick   160:b4a738a49916   A commit
#1  ^roll  161:1e21c4b1500c

After choosing your changes, you then choose c to commit them. The result is the following:

@ bfa4a3be drees tip | A commit o 788aa028 drees | Older stuff

If you are relatively new to them, then histedit can be a better choice than chistedit because it provides the command descriptions in histedit file for reference. It just takes a bit more editing to set the commands using normal text editing (just like normal rebase).

Note, to use either histedit or chistedit you need to add histedit to your extensions in your ~/.hgrc:

[extensions]
histedit =

I suggested chistedit since it is closest to rebase -i and works anywhere in the history. If you really just want subsume/tweak the current revision into the previous one then @G. Demecki's strip suggestion can be good since what is happening is clear. It is built in since Mercuria 2.8. To get the equivalent results as above you can do the following:

hg strip .
hg add
hg commit --amend

참고 strip, histedit처럼 활성화 될 필요가 당신의 ~ / .hgrc :

[extensions]
strip =

가장 최근 커밋 2 개를 스쿼시 (통합)한다고 가정 해 보겠습니다.

  1. 개정 번호 찾기

    hg log -G -l 3
    

    가능한 출력 :

    @  changeset:   156:a922d923cf6f
    |  branch:      default
    |  tag:         tip
    |  user:        naXa!
    |  date:        Thu Dec 13 15:45:58 2018 +0300
    |  summary:     commit message 3
    |
    o  changeset:   155:5feb73422486
    |  branch:      default
    |  user:        naXa!
    |  date:        Thu Dec 13 15:22:15 2018 +0300
    |  summary:     commit message 2
    |
    o  changeset:   154:2e490482bd75
    |  branch:      default
    ~  user:        naXa!
       date:        Thu Dec 13 03:28:27 2018 +0300
       summary:     commit message 1
    
  2. 소프트 리셋 분기

    hg strip --keep -r 155
    
  3. 변경 사항을 다시 커밋

    hg commit -m "new commit message"
    

노트

strip사용하려면 기본 제공 확장이 필요합니다. ~/.hgrc다음 내용으로 구성 파일을 생성 / 편집 합니다.

[extensions]
strip = 

나는 사용한다:

hg phase --draft --force -r 267
...
hg rebase --dest 282 --source 267 --collapse

참고 URL : https://stackoverflow.com/questions/1725607/can-i-squash-commits-in-mercurial

반응형