72

私は Mercurial に比較的慣れていないので、私のチームは現在、Subversion の代わりとして Mercurial を試しています。

作業ディレクトリの他の変更をコミットせずに (または少なくとも他のリポジトリにプッシュせずに)、単一のファイルをコミットして別のリポジトリにプッシュするにはどうすればよいですか?

これは、データベースの移行で発生します。ソース管理への移行をコミットして、データベースの移行に伴うコードの変更に取り組んでいる間、DBA がそれを表示および編集できるようにします。変更はまだ準備が整っていないため、すべてをプッシュするつもりはありません。

転覆では、私は単純に次のようにします:

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

そして地元で働き続ける。

これはmercurialでは機能しません.他のリポジトリにプッシュするとき、プルしていない変更がある場合は、それらをプルダウンしてマージし、そのマージをコミットする必要があります.リポジトリ。マージ後のコミットでは、ファイルを省略できないため、ローカル リポジトリ内のすべてをコミットする必要があります。

私が理解できる最も簡単な方法は、ファイルをローカル リポジトリにコミットし、ローカル リポジトリのクローンを作成し、実際のリポジトリから新しい変更を取得し、それらをマージしてそのマージをコミットし、それらが私の変更をプッシュすることです。

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

これは機能しますが、何か簡単なものが欠けているように感じます.Mercurialに作業ディレクトリに既にあるファイルを無視するように指示する方法です.マージを実行してファイルを送信するだけです. Mercurial キューでこれができると思いますが、まだ mq を完全には理解していません。

4

6 に答える 6

40

最初にこの質問をしてからほぼ 2 年が経ちました。今は別の方法で行います(上記の質問の上のコメントで述べたように)。代わりに、変更をローカル リポジトリ内の 1 つのファイルにコミットします (hg レコード拡張子を使用して、ファイルの一部のみをコミットできます)。

hg commit -m "commit message" filename

あとは押し出すだけ。

hg push

最初にマージする必要があるリポジトリに他の変更が加えられたために競合が発生した場合は、親リビジョンに更新します (それが何であるかわからない場合は "hgparent -r ." で表示されます)、コミットします。私の他の変更はそこにあるので、2 つの頭があります。次に、元の単一ファイルのコミットに戻り、変更をそのバージョンにプル/マージします。次に、変更を押し出します

hg push --rev .

単一のファイルとそのリビジョンのマージのみをプッシュする。次に、ローカルにある 2 つのヘッドをマージできます。

この方法では、mq の要素と拒否されたハンクの可能性を取り除き、ソース管理によってすべてを追跡できます。後でリビジョンが不要になった場合は、リビジョンを "hg strip" することもできます。

于 2010-07-13T17:33:39.953 に答える
31

shelveおよび unshelve コマンドを実装する Mercurial の機能があり、後で変更を保存するように指定するインタラクティブな方法を提供します: Shelve

hg shelve次に、hg unshelve変更を一時的に保存することができます。「パッチ ハンク」レベルで作業して、棚に置くアイテムを選択できます。追加のためにリストされていたファイルが棚上げされたようには見えず、変更されたファイルが既にレポにあるだけでした。

これは「拡張機能」として Mercurial に含まれています。これは、hg 設定ファイルで有効にする必要があることを意味します。


非常に古いバージョンの Mercurial に関する注意事項 (shelf が含まれる前 -- これは不要になりました):

いくつかのグーグルで素晴らしいインストール手順が表示されなかったので、これを機能させるために使用したものを組み合わせたものを次に示します。

次の方法で取得します。

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

プロジェクト内の (現在) 唯一のファイルは hgshelf.py ファイルです。

~/.hgrc を変更して、リポジトリのクローンを作成した場所を指す shelve 拡張機能を追加します。

[extensions] 
hgshelve=/Users/ted/Documents/workspace/hgshelve/hgshelve.py
于 2008-09-24T03:41:32.393 に答える
10

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

現在、すべての作業がパッチ キューに保存されているため、これらの変更を適用解除して、リモートの変更をプルした後に復元できます。通常、すべてのパッチを適用解除するには、単にhg qpop -a. パッチ キューへの影響を示すために、一度に 1 つずつポップします。

$ 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

この時点で、ディレクトリに変更がないかのようになります。を行いhg fetchます。これで、パッチ キューの変更を元に戻して、競合があればそれらをマージできます。これは、概念的には git のリベースに似ています。

$ 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

この時点で、他のローカルの変更を維持しながら、移行をプッシュしました。他の変更は、キュー内のパッチにあります。私は個人的な開発のほとんどをパッチ キューを使用して行い、変更をより適切に構成できるようにしています。パッチ キューを削除して通常のスタイルに戻したい場合は、変更をエクスポートして「通常の」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

私は開発用のパッチ キューに非常にハマってmqおり、最も優れた実装の 1 つです。複数の変更を同時に作成できることで、コミットの集中度とクリーン度が大幅に向上します。慣れるまで少し時間がかかりますが、DVCS ワークフローとの相性は抜群です。

于 2009-02-20T12:39:22.010 に答える
3

拡張機能に依存したくない場合の別のオプションは、これらの種類の統合タスクにのみ使用するアップストリーム リポジトリのクローンをローカルに保持することです。

あなたの例では、変更を統合/上流リポジトリにプル/マージし、リモートサーバーに直接プッシュするだけです。

于 2008-10-10T01:35:31.860 に答える
1

あなたが最も簡単だと言ったので、hg commit -iファイル全体をコミットする場合でも (--interactive) を使用することがよくあります。コマンドラインでパス全体を入力するのではなく、必要なファイルを--interactive選択するだけです。追加のボーナスとして、ファイル内のチャンクを選択的に含める/除外することもできます。

そして、hg pushその新しく作成されたコミットをプッシュするだけです。

hg commit --interactiveこの回答での使用について詳しく説明します: https://stackoverflow.com/a/47931672/255961

于 2017-12-21T19:42:18.410 に答える