gitブランチを元のバージョンにリセットする必要があります


440

偶然、あるはずがないはずのブランチで作業していたので、適切な名前を付けてブランチから分岐しました。今度は、元のバージョン(github)にあるはずがないはずのブランチを上書きします。これを行う簡単な方法はありますか?ブランチを削除してからトラッキングブランチをリセットしようとしましたが、それは私が再び作業していたバージョンを取得するだけです。



Gitの2.23(2019年8月)付:git switch -C mybranch origin/mybranch以下の私の編集済みの回答を
VonC '30

回答:


814

まだオリジンにプッシュしていない場合は、次のコマンドでブランチを上流のブランチにリセットできます。

git checkout mybranch
git reset --hard origin/mybranch

(質問で言及したように、最新のコミットを別のブランチで参照していることを確認してください)

リセット直後は、リセットmybranch@{1}前の古いコミットを指すことに注意してください。

ただし、すでにプッシュしている場合は、「gitブランチを作成し、元の状態をアップストリームの状態に戻す」を参照してください。


Gitの2.23(2019年8月)、その1つのコマンドのようになります。git switch
つまり:git switch -C mybranch origin/mybranch

C:\Users\vonc\git\git>git switch -C master origin/master
Reset branch 'master'
Branch 'master' set up to track remote branch 'master' from 'origin'.
Your branch is up to date with 'origin/master'.

これにより、インデックスと作業ツリーが復元されますgit reset --hard


によるコメント Brad Hermanが、a reset --hard新しいファイル削除するか変更されたファイルをHEADにリセットします

実際、「白紙の状態」から始めることを確認するために、 git clean -f -dするために、リセット後は、リセットしたブランチとまったく同じ作業ツリーが確実に動作するようになります。


このブログ投稿はこれらのエイリアスを提案しています(masterブランチのみですが、それらを適応/拡張することができます):

[alias]
   resetorigin = !git fetch origin && git reset --hard origin/master && git clean -f -d
   resetupstream = !git fetch upstream && git reset --hard upstream/master && git clean -f -d

次に、次のように入力できます。

git resetupstream

または

git resetorigin

26
これにより、(
Peter Ehrlich

5
git reset --hard origin/mybranchローカルでの変更を気にせず、発信元に一致するクリーンなコピーが必要なときに、コマンドを数回使用しました。しかし、今日、これは機能しませんでした-私はまだいくつかの新しいステージされていないファイルを持っていました、そしてgitはそれがHEADにあることを私に約束し続けました。git clean -f -d修正についてのメモは、不要な新しいファイルをすべて消去することで修正しました。
Matthew Clark

@MatthewClark予想されます:stackoverflow.com/q/4327708/6309の
VonC

1
すごい!またgit reset --hard HEAD、以前のコミットに戻って、変更を無視して何度も使用しました
daronwolff

これはsourctreeでも可能ですか?
Lonzak

20

これが起こったと仮定します:

# on branch master
vi buggy.py                 # you edit file
git add buggy.py            # stage file
git commit -m "Fix the bug" # commit
vi tests.py                 # edit another file but do not commit yet

次に、間違ったブランチに変更を加えることに気付きます。

git checkout -b mybranch    # you create the correct branch and switch to it

しかし、masterまだあなたのコミットを指しています。あなたはそれが以前に指し示した場所を指すようにしたいです。

解決

最も簡単な方法は次のとおりです。

git branch --force master origin/master

別の方法は:

git checkout master
git reset --soft origin/master
git checkout mybranch

使用reset --hardすると、コミットされていない変更が失われることに注意してください(tests.py私の例では)。


私の答えよりも安全だと思います;)+1
VonC

8

サーバーにプライベートリポジトリがあり、定期的にリベース/強制プッシュするため、他のコンピューターのローカルブランチを頻繁にリセットする必要があります。したがって、次のエイリアス「catchup」を作成しました。これにより、現在のブランチでこれを行うことができます。他の回答とは異なり、このエイリアスにはハードコーディングされたブランチ名はありません。

しっかりつかまる。

[alias]
  catchup = "!f(){ echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \"; read -r ans; if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)); else echo \"catchup aborted\"; fi }; f"

適切にフォーマットされた(.gitconfigの改行では機能しません)次のようになります。

"
!f(){
  echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \";
  read -r ans;
  if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then
    git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD));
  else
    echo \"catchup aborted\";
  fi
}; f
"
  • \\033[0;33m\\033[0m色で現在のブランチと上流を強調するためです。
  • $(git symbolic-ref -q --short HEAD) 現在のブランチ名です
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) 現在のブランチの上流です。

リセットは潜在的に危険な呼び出しであるため(特に--hardオプションを使用すると、コミットされていない変更は失われます)、最初に何をしようとしているのかが通知されます。たとえば、qcpp / dev-containerというリモートでブランチdev-containerを使用していて、と入力するとgit catchup、プロンプトが表示されます。

dev-containerをqcpp / dev-containerにリセットしますか?(はい/いいえ)

次にyと入力するか、単にreturnキーを押すと、リセットが実行されます。それ以外を入力すると、リセットは実行されません。

非常に安全で、ステージングされていない/コミットされていない変更がプログラムで失われないようにしたい場合は、diff-indexのチェックに従って、上記のエイリアスをさらにポンピングできます

警告の義務的な言葉:あなたが他の人々が基づいているパブリックリポジトリで作業していて、このエイリアスが必要な場合、それは間違っています™


1

私はこれを試しましたが、現在のブランチを最新のリモートgithubにリセットしませんでした。私はググってhttps://itsyndicate.org/blog/how-to-use-git-force-pull-properly/を見つけました

示唆した

git fetch origin master
git reset --hard origin/master

私は自分のv8ブランチをリセットしたかったので、

git fetch origin v8
git reset --hard origin/v8

そしてそれはうまくいった


さて、あなたがフェッチについて言及するのは良いことです。私は一度それをせずにすべてを2年前にリセットしました:)
Adam
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.