「git pull」は保留中の変更を自動的に隠してポップできますか?


122

私はこれを解決する方法を知っています:

user@host$ git pull
Updating 9386059..6e3ffde
error: Your local changes to the following files would be overwritten by merge:
    foo.bar
Please, commit your changes or stash them before you can merge.
Aborting

しかし、聞かせする方法はありませんgit pullstashし、pop私のために踊りますか?

このコマンドに別の名前が付いていても問題ありません。

のシェルエイリアスを作成することgit stash; git pull; git stash popが解決策ですが、より良い解決策を探しています。


何についてのgitの別名?
2015年

20
実行git stash; git pull; git stash pop隠しておくことは何もない場合は、ので、プログラムでは、危険であるgit stash無操作できなくなりますが、git stash popほぼ確実にある最後のスタッシュ(もしあれば)、ポップアップ表示されますではない、あなたが欲しいものを。ユーザーtorekがこれについてStack Overflowで素晴らしい投稿をしていますが、見つかりません...
jub0bs

2
@Jubobsこれ?stackoverflow.com/a/20412685/6309またはこれですか?stackoverflow.com/a/20480591/6309
VonC

1
@guettli私はあなたの質問が重複していることを示唆していませんでした、私はちょうどJubobsのコメントに答えていました。
VonC、2015年

2
さらに一歩として、引っ張った後にスタッシュをきれいに適用できる場合にのみ、操作は成功するはずです。競合がある場合、ツリー全体が変更されないように、操作全体がアトミックに失敗します。これは私がしたいことです:ローカルの変更をマージして変更をプルダウンするか、エラーで失敗して次に何をするかを手動で決定させます。この種のgit 'トランザクション'は可能ですか?
Ed Avis 2015年

回答:


185

Git 2.6以降(2015年9月28日リリース)

のみ git config 興味深い設定は次のとおりです。

rebase.autoStash

(Git 2.27、2020年第2四半期ではmerge.autostash、現在も使用可能です。以下を参照してください)

trueに設定すると、操作が始まる前に一時スタッシュが自動的に作成され、操作が終了した後に適用されます。
これは、ダーティなワークツリーでリベースを実行できることを意味します。

ただし、注意して使用してください。リベースが成功した後の最後のstashアプリケーションは、重要な競合を引き起こす可能性があります。デフォルトはfalseです。

それと組み合わせる:

pull.rebase

trueの場合、「git pull」が実行されたときにデフォルトのリモートからデフォルトのブランチをマージするのではなく、フェッチされたブランチの上にブランチをリベースします。

git config pull.rebase true
git config rebase.autoStash true

git pull汚れた木でも簡単に機能するにはそれで十分でしょう。
その場合、エイリアスは必要ありません。


参照してください53c76dcコミットにより(2015年7月4日)をケビンDaudt( )Ikke
(による合併Junio C浜野- gitster-e69b408をコミット 2015年8月17日)

pullrebase.autostash有効なときにダーティツリーを許可する

リベースは、ダーティーな作業ツリーに遭遇したときに変更を隠しておくことを学びましたが、git pull --rebaseそうではありません。

rebase.autostashが有効でない場合にのみ、作業ツリーがダーティかどうかを確認します。


注:autostash を使わずにrebase.autoStash true設定されていても)プルしたい場合は、git 2.9(2016年6月)以降です。

 pull --rebase --no-autostash

参照450dd1dをコミットし1662297をコミットし44a59ffコミット5c82bcdをコミットし6ddc97cをコミットしeff960bをコミットしefa195dコミット(2016年4月2日)、およびf66398eをコミットしc48d73bをコミットすることで(2016年3月21日)Mehulジャイナ教(mehul2029
(合併によりJunio C浜野- gitster-7c137bbコミット、2016年4月13日)

特にコミットf66398eには以下が含まれます。

pull --rebase--[no-]autostashフラグを追加

rebase.autoStash構成変数が設定されている場合git pull --rebase、コマンドラインから" " を上書きする方法はありません。

設定されている場合、の現在の値を上書きgit pull --rebaseする--[no-]autostashコマンドラインフラグを" "に教えますrebase.autoStash。「git rebase」は--[no-]autostashオプションを理解するのでgit rebase、「git pull --rebase」が呼び出されたときにオプションを「」に渡すだけです。


警告:Git 2.14(2017年第3四半期)より前のバージョンでgit pull --rebase --autostashは、ローカル履歴がアップストリームに早送りされたときに、「」は自動スタッシングを行いませんでした。

Tyler Brazier()によるcommit f15e7cf(2017年6月1日)を参照してください。(合併によりJunio C浜野- -コミット35898ea、2017年6月5日)tylerbrazier
gitster

pull:ff --rebase --autostashはダーティーリポジトリで動作します

git pull --rebase --autostashダーティーリポジトリで早送りが発生した場合、何も自動保存されておらず、プルに失敗しました。
これは、早送りできるときにリベースを実行しないようにするショートカットが原因でしたが、そのコードパスではautostashは無視されます。


更新:Mariusz Pawelskiコメントで興味深い質問をしています:

したがって、autostashリベース(またはpull --rebase)を実行するタイミングについては、誰もが書いています。

しかし、マージで通常のプルを行う場合、自動スタッシングについて誰も気にしていません。
そのための自動スイッチはありませんか?または、何か不足していますか?私はやりたいのですgit pull --rebaseが、OPは「標準」のgit pull について尋ねました

回答:

元のスレッドこのautostash機能を議論は、それがために、本来の両方に実装されたgit pull(マージ)とgit pull --rebase

しかし... Junio C Hamano(Gitメンテナー)は次のように述べています:

pull-mergeこのトピックをトリガーした「煩わしさ」を誘発するものであった場合、定義により、ローカルの変更はマージと重複し、この内部の「スタッシュポップ」はマージが触れたパスに影響し、おそらく「ドロップ」にはなりません。 「しかし、解決すべきさらなる紛争を残します。

pull.autostash構成は悪い、苦痛を引き起こすワークフローを助長するので、良い追加ではないと思います。
単純なケースでは害はないかもしれませんが、ローカルの変更が複雑な場合、それがないことよりも積極的に害を及ぼし、構成は選択するインセンティブを奪います。

「pull-rebase」の場合、方程式は多少異なります。「rebase」ではクリーンな作業ツリーから開始するように要求されるため、「ダウンロードしてから停止」の煩わしさが大きく感じられます。私は本当の問題のより生産的な修正であるかもしれない緩めるのではないかと疑っています。

したがって、古典的なプルマージに関しては、次のようにするのがよいでしょう。

git pull」を実行する前に、ユーザーが作業ツリーで持っているWIPの性質について考えることをユーザーに促します
他の人がしていることに干渉するかもしれないそれはあまりにも複雑な獣ですか、それとも彼が隠してそれを取り戻すことができる些細な変化ですか?

前者の場合、「checkout -b」を実行する方がはるかに優れており、ローカルの変更がいくらか良い形になり、「コミット」するまで作業を続けてから、元のブランチに移動します。

後者の場合、彼は次のことをする方が良いです:

  • git pull」、
  • それが競合していることを発見した後、実行します
    • git stash
    • git merge FETCH_HEAD そして
    • git stash pop

そうは言っても、Git 2.27(2020年第2四半期)では、「git pull」はpull.rebase構成が存在せず、どちら--[no-]rebase--ff-only指定されていない場合に警告することを学びました(マージの結果になります)。

Alex Henrie(によるコミットd18c950(2020年3月10日)を参照してください。(合併によりJunio C浜野- -1c56d6fコミット 2020年3月27日)alexhenrie
gitster

pull:ユーザーがリベースするかマージするかを言わなかった場合に警告する

サインオフ:Alex Henrie

多くの場合、初心者のGitユーザーは " pull --rebase"と言うのを忘れて、アップストリームからの不要なマージが発生します。

彼らが通常望んでいるのは、 " pull --rebase"単純なケースでは " pull --ff-only" または " "メインの統合ブランチのコピーを更新し、作業を個別にリベースすることです。設定変数は単純な例でそれらを助けるために存在しているが、それのこれらのユーザーに認識させるためのメカニズムはありません。
pull.rebase

--[no-]rebaseコマンドラインからオプションがなく、pull.rebase構成変数が指定されていない場合、警告メッセージを発行します。
これはpull --rebase、特別なことをする必要がなかった" "をしたくない人には不便ですが、不便の費用はユーザーごとに1回だけ支払われます。


Git 2.27(2020年第2四半期)では、「git merge」が「--autostash」オプションと新しいmerge.autostash設定を学習します。

参照d9f15d3をコミットしf8a1785をコミットしa03b555コミット804fe31をコミットし12b6e13をコミットし0dd562eコミット0816f1dコミット9bb3deaコミット4d4bc15をコミットしb309a97をコミットしf213f06をコミットし86ed00aをコミットしfacca7fコミットbe1bb60をコミットしefcf6cfをコミットしc20de8bをコミットしコミットbfa50c2コミット3442c3dコミット5b2f6d9(2020年4月7日)、コミット65c425a(2020年4月4日)、およびfd6852cコミットしDenton Liu(Denton-Lによって805d9ea(2020年3月21日)をコミットします。
(合併によりJunio C浜野- gitster-bf10200コミット 2020年4月29日)

pull:--autostashを渡してマージします

サインオフ:Denton Liu

以前はで--autostashのみ機能していましたgit pull --rebase

ただし、前回のパッチでは、マージも学習さ--autostashれたため、この制限が必要になる理由はありません。リベースの場合と同じように、
プルを渡し--autostashてマージに渡します。

そして:

rebaseapply_autostash()sequencer.cから使用

サインオフ:Denton Liu

apply_autostash()関数は、受け入れる引数のタイプを除いて、ほとんど互換性があるという点で関数builtin/rebase.cと十分に似ていapply_autostash()ますsequencer.c。確認しsequencer.cたバージョンexternをすると、リベースでそれを使用します。

リベースバージョンがで導入された6defce2b02(「リベース組み込み:サポート--autostashオプション」、2018年9月4日、Gitのv2.20.0-RC0 - マージに記載されているバッチ#8)Cへの変換シェルの一部として。
当時、インタラクティブなリベースをシェルからCに変換する別の進行中のプロジェクトもあり、彼らはのsequencer.cバージョンをリファクタリングすることでそれらと衝突したくなかったため、関数を複製することにしましたapply_autostash()
両方の取り組みが長い間行われているので、自由に組み合わせることができます。


2.4.2現在、これはまだ実装されていません。たぶんいつか。 rebase.autoStashリベースを使用する場合にのみ適用されます。 pull.rebaseプルを使用する場合にのみ適用されます。
Randal Schwartz、2015年

「単純なgit pullがダーティツリーでも機能するのにそれで十分です。」ランダルがコメントしたように、これはまだ真実ではありません。現在のマスターのpull.cは引き続きを選択しdie_on_unclean_work_treeます。
Pradhan

1
@Pradhan同意する。実装は今朝マスターになり、git 2.6に対応する必要があります。私はそれを明確にするために答えを編集しました。
VonC

autostashがgitで動作していることを確認しました2.5.5
ジョシュアホブリット16

1
そのため、あなたがrebase(またはpull --rebase)するとき、誰もがautostashについて書いています。しかし、通常のpullマージで行う場合、誰も自動スタッシングに取り掛かっていません。そのための自動スイッチはありませんか?または、何か不足していますか?私はやりたいのですgit pull --rebaseが、OPは「標準」について尋ねましたgit pull
Mariusz Pawelski

41

次の探検家のために数秒を節約するために、ここに要約があります(@VonCに感謝):

git pull --rebase --autostash

6
ポイントは、git config pull.rebase trueとの 後、git config rebase.autoStash true必要なのはだけですgit pull。ただgit pull。他のオプションは必要ありません。
VonC

3
--autostashオプションには少なくともGit 2.9が必要なようです。-c rebase.autoStash=true以降のGit 2.6で動作します。
ntc2 2017

15

上記のコメントで述べたgit pullように、autostash構成は実際のリベースにのみ適用されるため、2つの構成値の設定は現在で機能しません。これらのgitコマンドはあなたが望むことをします:

git fetch
git rebase --autostash FETCH_HEAD

または、エイリアスとして設定します。

git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD'

次に行います:

git pullr

もちろん、このエイリアスは必要に応じて名前を変更できます。


7

Git 2.6以降では、以下を使用できます。

alias gup='git -c rebase.autoStash=true pull --rebase'

これ--rebaseにより、のrebase代わりにgit-pullが使用されるmergeため、などの設定/オプション--ff-onlyは適用されません。

--ff-onlyデフォルトでプルするエイリアス(git pull --ff-only)を使用しgupていますが、早送りマージができない場合や変更が隠されている場合に(上から)使用できます。


主な違いは何ですかgit pull --ff-onlyとはgit pull pull --rebase --autostash
アルパース

0

あなたがすでに述べたように、これはそれを行う方法です。入力を節約してショートカットを使用するためにエイリアスで使用することも、1行で使用することもできます(エイリアスにすることもできます)。

git stash && git pull --rebase && git stash pop

それはあなたがしたのと同じことを行いますが、単一行(&&)であり、エイリアスとして設定すると、さらに短くなります。

次の行は、プル/プッシュする前に着信/発信の変更を表示します

git log ^master origin/master
git log master ^origin/master

8
このアプローチは安全ではありません。隠してstash popおくものが何もない場合、最初のコマンドは何もせず、ランダムなものを以前からいくつか隠します。
John Zwinck 2017年

ただ、余分明確にする:場合でも、git stash&&はまだしてまいりますので、スタッシュ何でも、それはまだ「リターン」ノーエラーコードがないgit pullgit stash pop、前のスタッシュをポップ。したがって、何かを隠しておくことが確実でない限り、これを使用しないことをお勧めします。
MoonLite
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.