Program Tip

다른 수정 사항은 그대로두고 단일 파일을 커밋하고 푸시하는 가장 쉬운 방법은 무엇입니까?

programtip 2020. 10. 27. 23:07
반응형

다른 수정 사항은 그대로두고 단일 파일을 커밋하고 푸시하는 가장 쉬운 방법은 무엇입니까?


나는 상대적으로 Mercurial을 처음 접했고 우리 팀은 지금 Subversion을 대체하기 위해 그것을 시도하고 있습니다.

내 작업 디렉토리의 다른 수정 사항을 커밋하지 않고 (또는 적어도 다른 리포지토리로 푸시하지 않은 상태로) 단일 파일을 커밋하고 다른 저장소로 푸시하려면 어떻게해야합니까?

이것은 데이터베이스 마이그레이션에서 발생합니다. 우리는 DBA가 데이터베이스 마이그레이션과 함께 코드 수정 작업을하는 동안 소스 제어로 마이그레이션을 커밋하려고합니다. 변경 사항은 아직 준비되지 않았으므로 모두 밀어 내고 싶지 않습니다.

Subversion에서는 간단히 다음을 수행합니다.

svn add my_migration.sql  
# commit only the migration, but not the other files I'm working on
svn commit -m "migration notes" my_mygration.sql

로컬에서 계속 작업합니다.

이것은 내가 그것을 다른 저장소로 밀어 넣을 때 수은과 함께 작동하지 않습니다. 만약 내가 가져 오지 않은 변경 사항이 있다면, 그것들을 가져 와서 병합하고 그 병합을 커밋하기를 원합니다. 저장소. 병합 후 커밋은 파일을 생략 할 수 없으므로 로컬 저장소의 모든 항목을 커밋해야합니다.

내가 알아낼 수있는 가장 쉬운 방법은 파일을 내 로컬 리포지토리에 커밋하고 내 로컬 리포지토리를 복제하고 실제 리포지토리에서 새 변경 사항을 가져 와서 병합하고 해당 병합을 커밋 한 다음 변경 사항을 푸시하는 것입니다.

hg add my_migration.sql 
hg commit -m "migration notes" my_migration.sql 
cd ..
hg clone project project-clone
cd project-clone
hg fetch http://hg/project
hg push  http://hg/project

이것은 작동하지만 더 쉬운 것을 놓친 것처럼 느껴집니다. 머큐리 알에게 이미 내 작업 디렉토리에있는 파일을 무시하도록 지시하고 병합을 수행하고 파일을 함께 보냅니다. 나는 수은 대기열이 이것을 할 수 있다고 생각하지만 아직 완전한 mq는 아닙니다.


shelve 및 unshelve 명령을 구현하는 Mercurial 기능이 있습니다.이 기능은 나중에 저장하도록 변경 사항을 지정하는 대화식 방법 인 Shelve를 제공 합니다.

그럼 당신은 할 수 hg shelvehg unshelve잠시 자리를 비운 변경 사항을 저장합니다. 이를 통해 "패치 덩어리"수준에서 작업하여 보관할 항목을 선택하고 선택할 수 있습니다. 추가를 위해 나열된 파일을 보관하지 않는 것처럼 보였으며 이미 수정 된 파일 만 저장소에 있습니다.

Mercurial에 "확장자"로 포함되어 있으므로 hg 구성 파일에서 활성화해야합니다.


Mercurial의 정말 오래된 버전에 대한 참고 사항 (Shelve가 포함되기 전-더 이상 필요하지 않음) :

인터넷 검색에서 훌륭한 설치 지침을 보지 못했기 때문에 다음은 작동하도록하는 데 사용한 조합입니다.

함께 가져 오기 :

hg clone http://freehg.org/u/tksoh/hgshelve/ hgshelve

프로젝트의 유일한 파일 (현재)은 hgshelve.py 파일입니다.

~ / .hgrc를 수정하여 저장소를 복제 한 위치를 가리키는 shelve 확장을 추가하십시오.

[extensions] 
hgshelve=/Users/ted/Documents/workspace/hgshelve/hgshelve.py

이 질문을 처음 제기 한 지 거의 2 년이 지났습니다. 나는 지금 다르게 할 것입니다 (위의 질문 위의 의견에서 언급했듯이). 이제 내가 할 일은 로컬 저장소의 한 파일에 변경 사항을 커밋하는 것입니다 (hg 레코드 확장을 사용하여 파일 조각 만 커밋 할 수 있음).

hg commit -m "commit message" filename

그런 다음 밀어냅니다.

hg push

먼저 병합해야하는 리포지토리에 다른 변경 사항이 적용되어 충돌이 발생하는 경우 부모 개정으로 업데이트합니다 (무엇인지 모를 경우 "hg parent -r"으로 표시됨), commit 내 다른 변경 사항이 있으므로 머리가 2 개 있습니다. 그런 다음 원래 단일 파일 커밋으로 되돌리고 변경 사항을 해당 버전으로 가져 오거나 병합합니다. 그런 다음

hg push --rev .

단일 파일 만 푸시하고 해당 개정판을 병합합니다. 그런 다음 로컬에있는 두 개의 헤드를 병합 할 수 있습니다.

이 방법은 mq 항목과 거부 된 덩어리에 대한 가능성을 제거하고 소스 제어로 모든 것을 추적합니다. 나중에 원하지 않는 개정판을 "hg 제거"할 수도 있습니다.


tl; dr : 원래 설명이 복잡해 보이지만 패치 대기열을 사용하는 방법을 완전히 설명했으면합니다. 짧은 버전은 다음과 같습니다.

$ hg qnew -m "migration notes" -f migration my_migration.sql
$ hg qnew -f working-code
# make some changes to your code
$ hg qrefresh # update the patch with the changes you just made
$ hg qfinish -a # turn all the applied patches into normal hg commits

Mercurial Queues는 이런 종류의 일을 쉽게 만들고 변경 세트의 더 복잡한 조작을 가능하게합니다. 배울 가치가 있습니다.

이 상황에서 먼저 변경 사항을 적용하기 전에 현재 디렉토리에있는 내용을 저장하고 싶을 것입니다.

# create a patch called migration containing your migration
$ hg qnew -m "migration notes" -f migration.patch my_migration.sql
$ hg qseries -v # the current state of the patch queue, A means applied
0 A migration.patch
$ hg qnew -f working-code.patch # put the rest of the code in a patch
$ hg qseries -v
0 A migration.patch
1 A working-code.patch

이제 작업 코드에 대해 몇 가지 추가 작업을 수행해 보겠습니다. 저는 계속해서 qseries명시 적으로 설명 할 것입니다.하지만 일단 패치 대기열의 정신적 모델을 구축하면 목록을 계속 볼 필요가 없습니다.

$ hg qtop # show the patch we're currently editing
working-code.patch
$ ...hack, hack, hack...
$ hg diff # show the changes that have not been incorporated into the patch
blah, blah
$ hg qrefresh # update the patch with the changes you just made
$ hg qdiff # show the top patch's diff

Because all your work is saved in the patch queue now, you can unapply those changes and restore them after you've pulled in the remote changes. Normally to unapply all patches, just do hg qpop -a. Just to show the effect upon the patch queue I'll pop them off one at a time.

$ hg qpop # unapply the top patch, U means unapplied
$ hg qseries -v
0 A migration.patch
1 U working-code.patch
$ hg qtop
migration.patch
$ hg qpop
$ hg qseries -v
0 U migration.patch
1 U working-code.patch

At this point, it's as if there are no changes in your directory. Do the hg fetch. Now you can push your patch queue changes back on, and merge them if there are any conflicts. This is conceptually somewhat similar to git's rebase.

$ hg qpush # put the first patch back on
$ hg qseries -v
0 A migration.patch
1 U working-code.patch
$ hg qfinish -a # turn all the applied patches into normal hg commits
$ hg qseries -v
0 U working-code.patch
$ hg out
migration.patch commit info... blah, blah
$ hg push # push out your changes

At this point, you've pushed out the migration while keeping your other local changes. Your other changes are in an patch in the queue. I do most of my personal development using a patch queue to help me structure my changes better. If you want to get rid of the patch queue and go back to a normal style you'll have to export your changes and reimport them in "normal" mercurial.

$ hg qpush
$ hg qseries -v
0 A working-code.patch
$ hg export qtip > temp.diff
$ rm -r .hg/patches # get rid of mq from the repository entirely
$ hg import --no-commit temp.diff # apply the changes to the working directory
$ rm temp.diff

I'm hugely addicted to patch queues for development and mq is one of the nicest implementations out there. The ability to craft several changes simultaneously really does improve how focused and clean your commits are. It takes a while to get used to, but it goes incredibly well with a DVCS workflow.


Another option if you don't want to rely on extensions is to keep a clone of your upstream repository locally that you only use for these sorts of integration tasks.

In your example, you could simply pull/merge your change into the integration/upstream repository and push it directly up to the remote server.


What i use generally is use to commit a single file :

 hg commit -m "commit message" filename

In case later, I have a merge conflict and I am still not ready to commit my changes,follow these steps:

1) Create a patch file.

hg diff > changes.patch

2) Revert all your outstanding uncommitted changes, only after checking your patch file.

hg revert --all

3) Pull,update and merge to latest revision

hg pull -u
hg merge
hg commit -m "local merge"

4) Now simply import your patch back and get your changes.

hg import --no-commit changes.patch

Remember to use -no-commit flag from auto committing the changes.


Since you said easiest, I often use hg commit -i (--interactive) even when committing whole files. With --interactive you can just select the file(s) you want rather than typing their entire path(s) on the command line. As an added bonus you can even selectively include/exclude chunks within the files.

And then just hg push to push that newly created commit.

I put more details on using hg commit --interactive in this answer: https://stackoverflow.com/a/47931672/255961

참고URL : https://stackoverflow.com/questions/125272/whats-the-easiest-way-to-commit-and-push-a-single-file-while-leaving-other-modi

반응형