Gitでブランチを削除した後、ブランチを回復できますか?


1067

を実行した場合git branch -d XYZ、ブランチを回復する方法はありますか?ブランチの削除コマンドを実行しなかったかのように戻る方法はありますか?


4
受け入れられた回答についての本当に素晴らしいメモは、ブランチが元々削除された場合でも機能することです!元々誤って削除された後、ローカルにないいくつかのブランチを回復しました。
theblang 2018年

回答:


1955

はい、git reflog削除したブランチの先端でコミットのSHA1を見つけて見つけることができるはずgit checkout [sha]です。そして、いったんコミットしたらgit checkout -b [branchname]、そこからブランチを再作成することができます。


この凝縮/ワンライナーバージョンの@Cascabelの功績です。

あなたは1つのステップでそれをすることができます:

git checkout -b <branch> <sha>

477
これは1つのステップで実行できますgit checkout -b <branch> <sha>
Cascabel

200
簡単なヒント-ブランチを削除したばかりの場合は、ターミナルに「削除されたブランチ<your-branch>(以前は<sha>)」のようなものが表示されます。そして、それは超簡単です-ちょうどそれを使用してください<sha>。例えば前述したように-git checkout -b <branch> <sha>
Snowcrash

6
ええ、端末を上にスクロールしてください(そうしなかった場合を除くCMD+K
neaumusic

42
デフォルトで省略されているgit reflog --no-abbrevフルを表示するために使用し<sha>ます。
jkulak 2015

5
削除されたブランチのshaを見つけるのに苦労していた私のような他の誰にとっても、私はできましたgit checkout remotes/origin/deleted_branch
ジェフアーウィン

161

ほとんどの場合、到達できないコミットはreflogにあります。したがって、最初に試すことは、コマンドgit reflog(のreflogを表示するHEAD)を使用してreflogを確認することです。

おそらく、コミットがまだ存在している特定のブランチの一部である場合は、コマンドを使用するほうが簡単ですgit reflog name-of-my-branch。これは、たとえばプッシュを強制した場合など、リモートでも機能します(追加のアドバイス:代わりに常にgit push --force-with-lease間違いを防ぎ、より回復可能にすることをお勧めします)。


コミットがreflogにない場合(おそらく、reflogに書き込まないサードパーティツールによって削除されたため)、そのようなコマンドを使用して見つかったコミットのshaにブランチをリセットすることで、ブランチを正常に回復しました(それは未解決のコミットをすべて含むファイルを作成します):

git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt

複数回使用する必要がある場合(またはどこかに保存する場合)、そのコマンドでエイリアスを作成することもできます...

git config --global alias.rescue '!git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt'

そしてそれを使って git rescue

見つかったコミットを調査するには、いくつかのコマンドを使用して各コミットを表示し、それらを調べます。

コミットメタデータ(作成者、作成日、コミットメッセージ)を表示するには:

git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

差分も確認するには:

git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

コミットを見つけたら、このコミットでブランチを作成します:

git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560

WindowsでGUIが好きなものについては、機能=> => を使用して、GitExtensionsでコミット(およびコミットされていないステージングファイル)を簡単に回復できます。RepositoryGit maintenanceRecover lost objects...


削除されたステージングされたファイルを簡単に回復する同様のコマンド:https : //stackoverflow.com/a/58853981/717372


2
巨大な助け。私はローカルリポジトリにはないコミットを失っていました。そこにある最初のコマンドは、サーバーでそれを見つけるのに役立ちました。+1
ショーンアドキンソン2017年

1
そのgit rescueエイリアスは天の恵みです!!! 貢献してくれてありがとう!
72A12F4E

2
あなたは私の命を救いました。
ジェドリンチ

最後に削除された分岐コミット<sha>がわからないため、Patrick Koorevaarの回答が役に立ちました。
Monir Khan

@モニール・カーンそして?何を結論づけるべきですか?Patrickの回答は、私のコマンドのコピー/貼り付けにすぎません(エラー:彼はコミットをフィルターするのを忘れました)...
Philippe

45

GUIを使用する場合は、gitkを使用して操作全体を実行できます。

gitk --reflog

これにより、ブランチが削除されていないかのようにブランチのコミット履歴を確認できます。次に、ブランチへの最新のコミットを右クリックして、メニューオプションを選択しますCreate new branch


28

上位投票ソリューションは、実際には要求された以上のことを行います。

git checkout <sha>
git checkout -b <branch>

または

git checkout -b <branch> <sha>

コミットするのを忘れた可能性がある最近のすべての変更と一緒に、新しいブランチに移動します。これは、特にブランチを失った後に「パニックモード」になっている場合は、意図していない可能性があります。

クリーナー(および単純)ソリューションは、(あなたが見つけた後、ワンライナーのようだ<sha>git reflog):

git branch <branch> <sha>

これで、現在のブランチもコミットされていない変更も影響を受けません。代わりに、新しいブランチのみがまで作成されます<sha>

チップでない場合でも機能し、短いブランチを取得でき<sha>ます。正​​しくなるまで、新しいブランチ名で再試行できます。

最後に、正常に復元されたブランチの名前を、名前が付けられた名前またはその他の名前に変更できます。

git branch -m <restored branch> <final branch>

言うまでもなく、成功の鍵は適切なコミットを見つけることでした<sha>。そのため、コミットには賢明な名前を付けてください:)


14

tfeの回答に追加:Gitソースの領域(git.gitリポジトリ内)にもgit-resurrect.shスクリプトがあり、contrib/役立つ場合があります。

git-resurrect <name>というブランチチップの痕跡を見つけよ<name>うとし、復活させようとします。現在、reflogでチェックアウトメッセージが検索され、-rメッセージもマージされます。-mおよびを使用する と-t、すべての参照の履歴がMerge <name> into other/ Merge <other> into <name>(それぞれ)コミットサブジェクトについてスキャンされます。これはかなり低速ですが、他の人のトピックブランチを復活させることができます。


1
/ usr / lib / git-core /をPATHに追加する必要がありましたが、今はそれでうまくいきました。しかし、それは私が望んでいた奇跡を実行しませんでした:(
AmanicA 2015年

10

次のコマンドを使用して、削除したブランチを見つけて取得しました。最初のステップは、gcbの説明からです。

$ git fsck --full --no-reflogs --unreachable --lost-found > lost
$ cat lost | cut -d\  -f3 > commits
$ cat commits | xargs -n 1 git log -n 1 --pretty=oneline

次に、コミットコメントに基づいてgit commit id(GIT-SHA)を探し、以下のコマンドで使用します。以前に見つかったGIT-SHAを使用して、NEW-BRANCHという新しいブランチをチェックアウトします。

$ git checkout -b NEW-BRANCH GIT-SHA

どうもありがとうございました。名前を検索するのに少し時間がかかりましたが、その価値はありました。コミットメッセージ文字列も検索する方法がある場合は、はるかに優れています。
モニールカーン

9

たとえば、reflogがない場合。reflogが有効になっていないベアリポジトリで作業していて、回復するコミットが最近作成されたため、最近作成されたコミットオブジェクトを見つけてそれらを確認する方法もあります。

.git/objectsディレクトリ内から実行:

find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit

これにより、過去12時間に作成されたすべてのオブジェクト(コミット、ファイル、タグなど)が検索され、コミットのみが表示されるようにフィルター処理されます。これらをチェックすることはそれから速いプロセスです。

最初にJakubの回答で述べたgit-ressurect.shスクリプトを試してみます。


1
素晴らしい代替案!ただし、コマンドはエラーをスローします。問題は、「12h」部分(実際には「h」)にあります。「h」を削除すると、問題なく動作しました。From man find: "-ctime n-ファイルのステータスが最後に変更されたのはn * 24時間前です。" したがって、過去12時間の予想される動作を実現するには、12を0.5に変更する必要もあります。
pagliuca 2013年

1
ここではOS X 10.8を使用しているため、上記の「検索」フラグは、出荷されるバージョンに基づいています。
ロバートナイト

1
ええ、問題はバージョンにあることを確認してください!それが私が最初にあなたの答えを支持した理由です!パラメータが異なる可能性があることを人々が理解できるようにコメントしました。
pagliuca 2013年

9

GitがインストールされていないGitHubユーザーの場合:

GitHubウェブサイトから復元したい場合は、API使用してリポジトリ関連のイベントのリストを取得できます。

最初

  • これらのSHA(コミットハッシュ)を見つけます。

    curl -i https://api.github.com/repos/PublicUser/PublicRepo/events

    ...またはプライベートリポジトリの場合:

    curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events

    (GitHubパスワードの入力を求められます)

    • (リポジトリが2要素認証を必要とする場合は、この回答に関する以下のコメントを参照してください。)

  • GitHubに移動し永久に削除される新しい一時ブランチを作成します(Chromeが推奨されます)。

   •ブランチに移動して、そのブランチを削除します。

   •   同じページで、再ロードせずに、DevTools、Networkパネルを開きます。準備してください...

   •[復元]をクリックします。新しい「ライン」に気づくでしょう。それを右クリックして「cURLとしてコピー」を選択し、このテキストをエディターで保存します。

   •コピーしたコード行の最後に追加します-H "Cookie="。これは次のとおりです。

次のようなものが得られるはずです。

    curl 'https://github.com/UserName/ProjectName/branches?branch=BranchSHA&name=BranchName' -H 'Cookie:' -H 'Origin: https://github.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US' -H 'User-Agent: User-Agent' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://github.com/UserName/ProjectName/branches' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'utf8=%E2%9C%93&authenticity_token=token' --compressed

最終段階

  • 「BranchSHA」をSHAハッシュに置き換え、BranchNameを目的の名前に置き換えます(ところで、Webからブランチの名前を変更するのは素晴らしいハックです)。あなたが遅すぎなかったなら、とにかくこのリクエストをする必要があります。たとえば、ターミナルにコピーして貼り付けます。

PS

これは「最も簡単な解決策」でも「正しい」解決策でもないかもしれませんが、誰かが便利だと思った場合に提供されます。


1
上記は依存しない数少ないものの1つでgit reflogあるため、たとえば、リモートブランチを削除して、コンピューターからアクセスできなくなったために、から有用なコールドを取得できない場合に役立ちましたreflog。注場合のGithub上のOAuthを使用するか、二要素認証curlコマンドの形式は以下のようになる。curl -u username:token https://api.github.com/user又はcurl -H "Authorization: token TOKEN" https://api.github.com/repos/USER_OR_ORG_NAME/REPO_NAME/events
TT--

@ TT--うわー、助けてくれて嬉しいです!そして認証トークンに関するあなたの貢献に感謝します:)
Maxim Mazurok

8

削除するブランチに別のブランチから到達できるかどうか私の理解から、あなたは安全にそれを削除することができます

git branch -d [branch]

そしてあなたの仕事は失われません。ブランチはスナップショットではなく、スナップショットへのポインタであることに注意してください。したがって、ブランチを削除すると、ポインタも削除されます。

別のブランチが到達できないブランチを削除しても、作業が失われることはありません。もちろん、コミットハッシュをチェックアウトするほど簡単ではありませんが、それでも実行できます。これが、Gitがを使用して到達できないブランチを削除できない理由-dです。代わりに、使用する必要があります

git branch -D [branch]

これは、Gitに関するScott Chaconの必見ビデオの一部です。彼がブランチとその削除方法について話している58:00分を確認してください。

GitHubのScott ChaconによるGitの紹介


7
これは質問への回答にどのように役立ちますか?
Dmitri Zaitsev 2015

6
ブランチはコンテンツを保持しないが実際にはポインタであることを質問者に伝える。ブランチを削除することを恐れる必要はありません。削除したブランチと同じコミットを指す新しいブランチを作成できます。この質問をしたときのことを今でも覚えています。2012年にさかのぼります。
fabiopagoti

1
AT LASTまで3つの画面をスクロールしなければなりませんでした。問題を解決する答えを見つけました。ブランチを削除すると、単なるポインタが削除されます。ここではデータ損失の状況はありません。回復する必要があるのは、どこを指しているかだけです。直接行く回答reflogはやり過ぎです。
RomainValeri

5

これらすべてをローカルで実行し、リポジトリがBitbucket Cloudにプッシュする前に目的の状態であることを確認してください。また、現在のリポジトリを複製して、これらのソリューションを最初にテストすることをお勧めします。

  1. ブランチを削除したばかりの場合は、ターミナルに次のようなものが表示されます。
    Deleted branch <your-branch> (was <sha>)

2.ブランチを復元するには、次を使用します:

    git checkout -b <branch> <sha>

頭の上の「シャ」がわからない場合は、次のことができます。

  1. 次のコマンドを使用して、削除したブランチの先端でコミットの「sha」を見つけます。
    git reflog
  1. ブランチを復元するには、以下を使用します。
    git checkout -b <branch> <sha>

コミットが参照ログにない場合:

  1. 次のようなコマンドを使用して、見つかったコミットのshaにブランチをリセットすることで、ブランチの回復を試すことができます。
    git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt

2.次のいずれかを使用して、各コミットを表示できます。

    git log -p <commit>
    git cat-file -p <commit>

4

削除されたブランチを回復するには、まずreflog履歴を確認し、

git reflog -n 60

ここで、nは最後のn回のコミットを指します。次に、適切な頭を見つけて、その頭でブランチを作成します。

git branch testbranch HEAD@{30}

4

私は、リモートからブランチをリベースして、不要なコミットをいくつかクリアしようとし、必要なものを適切に選択しました。もちろん、私はSHAを間違って書いた...

ここに私がそれらを見つけた方法があります(主にここでの答えに関するものからのより簡単なインターフェース/相互作用):

まず、ログに緩いコミットのリストを生成します。これらはガベージコレクターによってダンプされる可能性があるため、できるだけ早くこれを実行して作業を停止します。

git fsck --full --no-reflogs --unreachable --lost-found > lost

これにより、確認lostする必要があるすべてのコミットを含むファイルが作成されます。私たちの生活を簡素化するために、SHAのみを切り取りましょう:

cat lost | cut -d\  -f3 > commits

これで、確認する必要があるcommitsすべてのコミットを含むファイルができました。

Bashを使用しているとすると、最後のステップは次のとおりです。

for c in `cat commits`; do  git show $c; read; done

これにより、それぞれの差分とコミット情報が表示されます。そして、あなたが押すのを待ちますEnter。次に、必要なものをすべて書き留めてから、チェリーピックで入力します。完了したら、Ctrl-Cを押します。



1

最初にgit batchに移動して、次のようにプロジェクトに移動します。

cd android studio project
cd Myproject
then type :
git reflog

すべての変更のリストがあり、参照番号は参照番号を取得して
から、android studioまたはgit betchaからチェックアウトします。別の解決策は、参照番号を取得してandroid studioに移動し、gitブランチをクリックしてから、参照番号を過ぎたチェックアウトタグまたはリビジョンをクリックして、ブランチを作成します。


1

tfeの答えに加えて、コミットがガベージコレクションされていない場合を除き、上記のプロセスで回復できます。Gitブランチは、単にコミットツリー内の特定のコミットへのポインタです。ただし、ポインターを削除し、そのブランチのコミットが他の既存のブランチにマージされない場合、gitはそれをダングリングコミットとして扱い、ガベージコレクション中に削除します。これは定期的に自動実行される場合があります。

ブランチが既存のブランチにマージされておらず、ガベージコレクションされていた場合は、既存のブランチからブランチが分岐されたポイントまでのすべてのコミットが失われます。


1

関連する問題:「削除されたブランチの内容を知る方法」を検索した後、このページにアクセスしました。

多くの古いブランチを削除しているときに、新しいブランチの1つを誤って削除してしまったように感じましたが、回復するための名前がわかりませんでした。

最近削除されたブランチを知るには、以下を実行してください:

Git URLにアクセスすると、次のようになります。

https://your-website-name/orgs/your-org-name/dashboard

次に、最近、誰が何を削除したかを示すフィードを表示できます。


承知しました。上記の答えはGitHubに対するものです。GitHubをローカルにインストールしました。質問していただきありがとうございます。
Manohar Reddy Poreddy

1

私はブランチを削除するコンピューターでこれを行いました:

git reflog

応答:

74b2383 (develope) HEAD@{1}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2}: checkout: moving from develope to master
74b2383 (develope) HEAD@{3}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{4}: reset: moving to HEAD
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{5}: clone: from http://LOCALGITSERVER/myBigProject/Android.git

そして、私はこのコマンドでブランチを取得します:

git checkout -b newBranchName 74b2383


0

使用git reflogしただけでは返ってshaきませんでした。のみcommit id(8文字の長さで、SHAが道長いです)

だから私は git reflog --no-abbrev

次に、上記と同じことを行います。 git checkout -b <branch> <sha>


常に省略された8文字のshaを使用できます。完全なshaを使用する必要はありません
Michael Dreher

0

VSCodeを使用している場合... そしてブランチを削除する前のある時点でブランチをサーバーと同期した場合...

git branch deleteはローカルコピーのみを削除し、サーバー上のコピーは削除しないことに注意してください。まず、Gitパネル(左側のツールバーのgitアイコン)でブランチを調べ、ブランチが「origin / your_branch_name」の下にまだあるかどうかを確認します。その場合は、それを選択するだけで、コードを元に戻すことができます(ローカルの別の場所にすぐにコピー/貼り付け/保存することをお勧めします)。

「origin / your_branch_name」が表示されない場合は、GitLens拡張機能をインストールしてください。これにより、サーバーリポジトリを視覚的に調べて、サーバーに同期したコピーを見つけることができます。複数のリポジトリがある場合は、GitLensにリポジトリを表示するために、目的のリポジトリから少なくとも1つのファイルを開く必要がある場合があることに注意してください。次に:

  1. GitLensパネルを開く

  2. リポジトリを展開する

  3. カテゴリのリストが表示されるはずです:ブランチ/コントリビューター/リモート/ Stashes /など

YourLostTreasureは、「ブランチ」またはおそらく「リモート-> Origins」の下にあります。うまくいけば、目的の名前のブランチが表示されます。ブランチを展開すると、そのブランチで変更したファイルが表示されます。ファイル名をダブルクリックして開き、すぐにそのコードをバックアップします。

失われたブランチがすぐに表示されない場合は、あちこち見回して、何か有望なものが見つかった場合は、すぐに開いてコードを入手してください。TheGoldenBranchが見つかるまでかなり注意深く調べなければなりませんでしたが、それでもコードに最後の1つまたは2つの保存がありませんでした(おそらくブランチ-マージ-誤ってクリックする前にサーバーに同期できなかったためです)。 Branch-Delete)。私が最初にブランチを見つけたとき、名前が正しいことを完全に確信していなかったので探し続けたので、検索が不必要に長くなりました。(したがって、カルペCarpumと 、その後 探し続けます。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.