日付でGitでチェックアウトする方法?


314

私はソースコードの回帰に取り組んでいます。私はGitに「パラメーター化された日付/時刻に基づいてソースをチェックアウトする」と伝えたいと思います。これは可能ですか?

私はまた、失いたくない私の現在の見方の変化を上演しました。理想的には、現在のソースと、以前の日付に基づいて興味のあるバージョンとを交互に切り替えたいと思います。


9
あなたがそれについて知らない場合に備えて、Git bisectはリグレッションを見つけるのにとても素晴らしいです。私は、アンディが言ったように{1年前}の構文を使用して、既知の良好なコミットを見つけ、それを最初のgit bisect goodポイントとして使用します。
MatrixFrog 2011

これはの良い使用例だと思いtagsます。
ジェス2017年

回答:


365

現在の変更を維持するには

コミットせずに、で作業を隠しておくことができますgit stash。あなたはgit stash popそれを取り戻すために使うでしょう。または、(carleetoが言ったように)git commit別のブランチにそれをすることができます。

rev-parseを使用した日付によるチェックアウト

次のようにして、特定の日付でコミットをチェックアウトできますrev-parse

git checkout 'master@{1979-02-26 18:30:00}'

使用可能なオプションの詳細については、を参照してくださいgit-rev-parse

コメントで述べたように、このメソッドはreflogを使用して履歴内のコミットを見つけます。デフォルトでは、これらのエントリは90日後に期限切れになります。reflogを使用するための構文はそれほど冗長ではありませんが、90日間しか戻ることができません。

回転リストを使用して日付でチェックアウト

reflogを使用しないもう1つのオプションrev-listは、特定の時点でコミットを取得するために使用する方法です。

git checkout `git rev-list -n 1 --first-parent --before="2009-07-27 13:37" master`

マージによって持ち込まれたバージョンではなく履歴のみが必要な場合は、-first-parentに注意してください。それはあなたが通常望んでいることです。


2
@ロッキーロッキーの詳細を教えてもらえますか?コマンドラインで何を入力していますか、それが機能しないのはなぜですか?エラーメッセージが表示されますか?
アンディ

8
@Rocky:問題は、パラメーターを引用符で囲む必要があることです。それ以外の場合、bashは引数をスペースで区切ります。お試しくださいgit co 'master@{2 days ago}'
Mark Wilden

13
注:どこまでさかのぼるかによっては、reflog(しばらくすると有効期限が切れます)を使用するため、これが機能しない場合があります。「警告:「マスター」のログは...に戻るだけです」と表示されます。ロッキーのソリューションは常に機能します。git checkoutgit rev-list -n 1 --before="2009-07-27 13:37" master
Mark Nadig

3
バッククォートは廃止され、読みにくいため、回答を編集しました。サブシェル$(...)が推奨されます。
Amedee Van Gasse、2016年

1
@Andyハッピー40歳の誕生日、Andy!(それが1979-02-26が意味していたと仮定して:))
デビッド

123

アンディの解決策は私にはうまくいきません。ここで私は別の方法を見つけました:

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

Git:日付によるチェックアウト


3
上記のコマンドを実行error: unknown switch `n'すると、これを回避する方法がわかりますか?
Tim

15

これに沿って何かが必要なようです: 日付に基づくGitチェックアウト

言い換えれば、あなたrev-listはコミットを見つけ、チェックアウトを使って実際にそれを取得するのに使用します。

段階的な変更を失いたくない場合、最も簡単な方法は、新しいブランチを作成して、そのブランチにコミットすることです。ブランチ間をいつでも切り替えることができます。

編集:リンクがダウンしているので、ここにコマンドがあります:

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

2
素晴らしいリンク!したがってgit checkout branch@{date}、reflogが期限切れになると動作を停止しますが、を使用できますgit checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`
cdunn2001


9

私の場合、-n 1オプションは機能しません。Windowsでは、次の一連のコマンドが正常に機能することがわかりました。

git rev-list -1 --before="2012-01-15 12:00" master

これは、指定された日付の適切なコミットのSHAを返し、次に:

git checkout SHA

4

git rev-parseあなたが興味を持っている日がある場合@Andyによって提案された解決策は罰金を作品の日付をコミット。ただし、作成者の日付に基づいてチェックアウトしたい場合は、rev-parseその日付を使用してコミットを選択するオプションがないため、機能しません。代わりに、以下を使用できます。

git checkout $(
  git log --reverse --author-date-order --pretty=format:'%ai %H' master |
  awk '{hash = $4} $1 >= "2016-04-12" {print hash; exit 0 }
)

awk述部$1 >= "2016-04-12" && $2 >= "11:37"で時間の使用も指定したい場合。)


3

rev-listオプションでさらに進んで、(純粋に架空の例として)masterブランチから運用ブランチへの最新のマージコミットを検索する場合:

git checkout `git rev-list -n 1 --merges --first-parent --before="2012-01-01" production`

特定の日付の時点で本番サーバーにあるコードを見つける必要がありました。これは私にとってそれを見つけました。


2

ビルド時にリポジトリの正確なバージョンに戻れるようにしたい場合は、ビルド元のコミットにタグを付けることをお勧めします。

他の回答は、特定の時点でブランチの最新のコミットにリポジトリを戻すための手法を提供しますが、常に十分であるとは限りません。たとえば、ブランチからビルドし、後でブランチを削除したり、後でリベースしたブランチからビルドしたりすると、ビルドしたコミットが現在のブランチからgitで「到達不能」になる可能性があります。git内の到達不能オブジェクトは、リポジトリが圧縮されるときに最終的に削除される可能性があります。

コミットにタグを付けると、後でブランチをどのように処理しても(タグを削除しない限り)、タグが到達不能になることはありません。


これは私が探している答えを私に与えませんが、これまでに述べられていない局面を指摘するための良い言及に値します。これは、正しいバージョンに到達できない問題の原因となる可能性があります。
manuelvigarcia

1
git rev-list -n 1 --before="2009-07-27 13:37" origin/master

印刷された文字列(たとえばXXXX)を受け取り、次のようにします。

git checkout XXXX

2
これは@bartoszkp回答の複製ではありませんか?originへの参照を追加するだけで、他の回答に対するコメントになります...
manuelvigarcia

はい、実際には、ほとんどの場合、SHAが何であるかを知らない(私のように)何をコピーするかを明確にするだけです。私の場合、テキストは明確ではなく、これはソリューションを見つけた後のコードであり、コピーされていません。オプションも少し異なります
Luca C.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.