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


109

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

git rebase -i <some-commit-before>

스쿼시합니다.

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

답변:


88

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

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


그래, 나는 일반적인 질문에 대한 내 의견에서 좋아하는 속임수 질문에서 그 답을 찾았습니다. 나는 그것이 당신의 대답이라고 생각합니다.
Ry4an Brase 2009

4
참고 : Histedit 확장은 Mercurial 2.3 이상과 함께 배포됩니다. 활성화하기 만하면됩니다.
Paidhi 2015

1
Concatenating Changesets 문서에서 "repos"의 추상적 인 개념을 사용합니다. 어떻게 참조합니까? 예 : hg -R oldrepo export ... 생성 "abort : repository oldrepo not found!
Aleksandr Levchuk 2015-04-28

13
2 개의 커밋을 스쿼시하려고합니다. 10 개 이상의 명령 또는 대체 확장이있는 위키 페이지가 정말로 필요한가요?
Aleksandr Levchuk 2015 년

3
주석을 참조하십시오. Histedit는 이제 내장되어 있습니다. 활성화하기 만하면됩니다 (기본 명령이 히스토리를 수정하지 않기 때문).
Ry4an Brase

43

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

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


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


4
HG 스트립의 전체 명령은 다음과 같습니다 hg strip --keep --rev [rev] 어디 rev의 개정 번호가 먼저 마지막 스쿼시 할 커밋
니콜라스 FORNEY을

3
@NicolasForney 없음 정확히 --rev선택 사항이며, 전체 명령입니다hg strip --keep [rev]
G. Demecki

개정은 3.3.3에서 나를 위해 필수입니다 : hg help strip제공 hg strip [-k] [-f] [-n] [-B bookmark] [-r] REV..., 및 수정을 생략하는 것은 저를 제공합니다 abort: empty revision set.
Roman Starkov

3
사용 hg strip은 최선의 생각이 아닙니다. 정확히 안전하지 않습니다. 시도해보십시오 hg histedit. evolve 확장을 사용해보십시오.
Martin Thomson

git 사람들에게 가장 자연스러운 방법으로 보입니다.)
foo는

32

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에서 )


1
두 개의 커밋에 대한 "~ 2"를 어디에서 찾았습니까?
Mi-La

1
revsets 항목에 설명되어 있습니다. hg help revsets를 참조하십시오.
markand

13

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

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

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

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

접기 명령

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

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

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, c및 을 접고 싶다고 가정합니다 d. 넌 할 수있어

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

결과적으로

a -> i -> j

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


rebase가 해당 확장의 대부분 (아마 전부?) 사용 사례를 다루는 것처럼 보이며 확실히이 질문에서 묻는 것입니다. 이 확장 프로그램의 킬러 기능은 대체하는 수정본을 숨기는 것이 아니라 숨기는 것이지만, --keep리베이스 옵션이이를 다룹니다 (수정본을 비밀로 표시하거나 결과를 확인한 후 스트립을 사용함). 두 개의 rebase 명령 시퀀스를 사용하여 다른 개정간에 개정을 이동할 수도 있습니다.
Arthur Tacca

... 게다가, 정말 복잡한 일을하고 있다면 항상 로컬 저장소를 먼저 복제하여 백업으로 사용할 수 있습니다. 그것이 얼마나 드문 지 고려하면 완전히 새로운 확장 프로그램을 사용하는 방법을 배우는 것보다 덜 노력합니다.
Arthur Tacca

"NameError : name 'execfile'is not defined"— evolve가 기본적으로 석기 시대 인 Python 2로 작성되었음을 의미합니다.
Neil G

1
@NeilG mercurial은 아직 Python 3를 지원하지 않습니다.
Pulkit Goyal

2
@NeilG 그래, 수은 커뮤니티는 최대한 빨리 py3 지원을 받기 위해 열심히 노력하고 있습니다.
Pulkit Goyal

1

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

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

absorb 확장은 작업 디렉토리의 각 변경 사항을 가져 와서 해당 라인을 수정 한 시리즈의 커밋을 파악하고 해당 커밋의 변경 사항을 자동으로 수정합니다.
모호한 부분이있는 경우 (즉, 여러 커밋이 같은 줄을 수정 함) absorb는 해당 변경 사항을 무시하고 수동으로 해결되도록 작업 디렉터리에 그대로 둡니다.

기술 수준에서 hg absorb커밋되지 않은 모든 변경 사항을 찾고 변경된 각 줄을 명확한 이전 커밋에 매핑하려고 시도합니다.
명확하게 매핑 할 수있는 모든 변경 사항에 대해 커밋되지 않은 변경 사항은 적절한 이전 커밋에 흡수됩니다. 작업의 영향을받는 커밋은 자동으로 리베이스됩니다.
변경 사항을 분명한 이전 커밋에 매핑 할 수없는 경우 커밋되지 않은 상태로 유지되고 사용자는 기존 워크 플로로 대체 할 수 있습니다 (예 : 사용 hg histedit).

의 자동 다시 쓰기 논리는 hg absorb행 기록을 따라 구현됩니다. 이것은 hg histedit또는 git rebase에서 취하는 접근 방식과 근본적으로 다릅니다. 이는 여러 입력이 주어진 파일의 새 버전을 파생하기 위해 3 방향 병합 을 기반으로하는 병합 전략에 의존하는 경향이 있습니다. 버전.

이 접근 방식은 hg absorb가 모호한 응용 프로그램 커밋으로 변경 사항을 건너 뛴다는 사실과 결합되어 hg absorb는 병합 충돌이 발생하지 않습니다!

이제 모호한 응용 프로그램 대상이있는 줄을 무시하면 패치가 항상 고전적인 3 방향 병합을 사용하여 깔끔하게 적용될 것이라고 생각할 수 있습니다. 이 진술은 논리적으로 정확합니다. 그러나 그렇지 않습니다. hg absorb병합이 수행 hg histedit되거나 git rebase -i실패 할 때 병합 충돌을 피할 수 있습니다 .


0

나는 chistedit(Mercurial 2.3 이후에 내장 된) rebase -i순수한 Mercurial ( chistedit의 대화 형 버전 histedit)에 가장 가깝다고 생각 합니다 . histedit에서 fold명령은 rebase에 매핑 squash되고 roll명령은 rebase의 fixup. 히스토리 보기 문서를 참조하십시오.

다음은 간단한 예입니다. 다음이 있고 1e21c4b1의 모든 변경 사항을 이전 개정판으로 옮기고 이전 개정판의 메시지 만 유지한다고 가정합니다.

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

실행 hg chistedit -r b4a738a4하여 b4a738a4로 다시 기록을 편집 할 수 있습니다 . chistedit에서 1e21c4b1로 커서를 이동하고 r해당 개정판을 롤링 할 것임을 표시하려면 누르십시오 . histedit의 순서 (가장 오래된 것부터 최신 것 순)가 (가장 오래된 것에서 가장 오래된 것 순으로) 반전됩니다 hg log.

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

변경 사항을 선택한 후 c 커밋 합니다. 결과는 다음과 같습니다.

@ bfa4a3be drees 팁 | 커밋 o 788aa028 drees | 오래된 물건

당신이 그들에게 비교적 새로운 경우, 다음 histedit보다 더 나은 선택이 될 수 있습니다chistedit 익숙하지 않은 경우 참조를 위해 histedit 파일에 명령 설명을 제공하기 때문에 . 일반 텍스트 편집을 사용하여 명령을 설정하려면 약간의 편집이 필요합니다 (일반 리베이스처럼).

주 사용 하나에 histedit또는 chistedit당신은 추가해야histedit 귀하의 확장에 ~ / .hgrc :

[extensions]
histedit =

역사상 어디에서나 chistedit가장 가깝고 rebase -i작동 하기 때문에 제안 했습니다 . 현재 개정판을 이전 개정판으로 포함 / 조정하고 싶다면 @G. 데 멕키strip무슨 일이 일어나고 있는지 명확하기 때문에 제안은 좋을 수 있습니다. Mercuria 2.8부터 내장되어 있습니다. 위와 동일한 결과를 얻으려면 다음을 수행하십시오.

hg strip .
hg add
hg commit --amend

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

[extensions]
strip =

0

가장 최근 커밋 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 = 

-1

나는 사용한다:

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