如何查看分支上任何给定 git 提交的代码状态?
How to view status of code at any given git commit on a branch?
我有一个 master 分支,其中有几个月与 Web 项目相关的提交。
我有时需要通过浏览器查看网站在过去特定时间点的样子。
我目前checkout master分支,select时间点并创建了一个分支。然后我可以在那个时间点在浏览器中看到该站点。
我应该这样做还是有更简单的方法?
运行 git status
将为您提供分支的当前状态。暂存文件、未暂存修改文件、是否处于变基/合并等
为了在开发过程中持续查看站点,我建议使用本地服务器在本地为您提供站点服务,您可以在其中不断地 refresh
浏览器查看更改。
一种流行的方式(也用于 Github 页面)是通过 Jekyll 为网站提供服务。
您的方法是其中一种方法。
有几种方法可以更快地到达那里(一点点)。
如果您有某种网络 UI 可以查看存储库和相关提交(例如,如果您的存储库托管在 GitHub 或 BitBucket 上),您可以找出提交的 SHA1 散列并按散列执行结帐。命令将是:
git checkout <sha1>
如果您对相对于某个时间点的状态感兴趣,您可以使用一个简单的命令首先找到 "closest" 提交哈希,然后检查它。例如,如果您需要查看代码在 2017 年 3 月 1 日的状态,您实际上对发生在 03/01/2017 00:00 之前的最新提交感兴趣。命令将是:
git checkout `git rev-list -n 1 --before="2017-03-01 00:00" master
值得一提的是,如果您 运行 正在使用 Windows,则需要使用略有不同的语法。这是相同代码的 PowerShell 版本:
$sha = git rev-list -1 --before="2017-03-01 00:00" master
git checkout $sha
最后,如果您知道某个提交代表了这些时间点之一,您以后会need/want回来,您可以使用Git稍后标记功能和结帐标签。例如,要标记提交,您可以 运行(将 sha1 替换为提交哈希 ):
git tag -a some-point-in-time <sha1>
当你想"come back"到这个时间点你可以运行:
git checkout -b master some-point-in-time
您可以在特定的早期提交处检出 master
分支,例如
git checkout <SHA-1 of some commit in master>
这将使您进入分离的 HEAD 状态。从这里,您可以实际构建您的项目、部署并查看它的外观。
如果您想从较早的提交创建一个真正的分支,您可以通过以下方式进行:
git checkout -b new_branch_from_old_commit
您很可能不需要创建新分支。环顾四周后,您可以 return 到您当前的 master
分支,只需检查一下即可:
git checkout master
您可以简单地 git checkout
通过哈希 ID 进行提交,尽管这听起来很可怕 "detached HEAD".
背景
分支和标签是命名某些特定提交的方式。就此而言,HEAD
只是一种命名分支的方式,或者有时是一个特定的提交。
因此:
git log
显示您从 HEAD
开始提交,并且:
git log master
显示您从 master
开始提交。如果HEAD
个名字master
,这两个做的事情完全一样。
添加--oneline
,或者我偏爱"DOG"—--decorate --oneline --graph
;还要考虑 "A DOG"、--all --decorate...
——稍微压缩输出:
* e0688e9 (HEAD -> master, origin/master, origin/HEAD) git svn: fix ...
* 3bc5322 First batch after 2.12
* 3e5c639 Merge branch 'rl/remote-allow-missing-branch-name-merge'
在这里我们看到 HEAD
名称 master
,还有两个提交名称 e0688e9
。
每个提交都会命名一个先前的提交(它的父提交)。这是如何 git log
能够显示多个提交。我们说分支和标签名称 指向 像 e0688e9
这样的提交,并且那个提交指向它的前身 3bc5322
,它又指向另一个,等等。
如果我们将这些绘制为一系列单字母名称提交(比 3bc5322...
哈希 ID 更实用),我们会得到如下所示的内容:
A <- B <- C <-- master
此处名称 master
指向 C
,C
指向 B
,B
指向 A
。 A
是有史以来第一次提交,所以它 不能 指向任何更远的地方,也不会。这就是 git log
知道 停止的方式!
分离头
通常,HEAD
包含实际的分支名称。在上面的 git log
输出中,我们看到 HEAD
名为 master
。正在做:
git checkout branch
告诉 Git 不仅要检查 branch
命名的特定提交,还要将 name branch
放入 HEAD
。我们说 HEAD attached 到分支。但是我们可以通过将原始哈希 ID 放入 HEAD
来 分离 它,我们通过 运行:
git checkout 3bc5322
这与在那里有一个分支名称的作用相同,除了 ...
新提交移动分支
当您进行 新 提交时,Git 将新提交写回当前提交,然后更改 当前分支 以便它指向新的提交。例如,如果我们添加一个新的提交 D
到我们的三提交 A-B-C
设置中,提交本身看起来像这样:
A <- B <- C <- D
但是 D
的名字是那些丑陋的大哈希 ID 之一,我们无法记住它。相反,我们让 Git 帮我们记住它——将它写入当前分支的名称。如果当前分支是 master
,这将更改 master
,使其不再指向 C
:
A <- B <- C <- D <-- master
现在master
为我们记住了D
,树枝本身也长大了!
但是,问题来了:Git 知道要更新哪个分支的方式是它存储在 HEAD
中。如果您有一个分离的 HEAD,则没有当前分支 name。在这种情况下,Git 将新提交 仅 记住为 HEAD
。假设我们添加 D
,同时我们通过哈希 ID 签出 B
:
A--B--C <-- master
\
D <-- HEAD
如果我们 git checkout master
,那会用名称 master
覆盖 HEAD
,"forgetting" 我们的新提交。
这并不是真的危险,除非它可能是:也许你写了一些非常棒的代码,你会 never be able to write again,但现在你已经失去了它,哦不!因此,为此目的,您可以在任何提交时 创建一个新的分支名称 , 包括 一个分离的 HEAD,使用 git checkout -b
:
git checkout -b newbranch
现在我们有:
A--B--C <-- master
\
D <-- newbranch (HEAD)
或者,当然,您可以给提交 B
一个标签,然后检查它,然后创建新的提交 D
。这里的要点是 commits 才是真正重要的;这些名称只是给我们 找到它们的方法。
命名提交的方式有很多种
您可以使用分支和标签名称,但您可以添加后缀和计数:
HEAD~1
例如表示"start at HEAD, but then walk back once to HEAD's parent"。 (如果提交是 merge commit——一个有多个父项——~
后缀选择 first 父项,每次.) 或者,您可以将 @{...}
与 HEAD
或分支名称一起使用:
master@{1.week.ago}
它使用 Git 调用 master
的 reflog 来查看哪个提交 master
恰好在一周前命名(如果那是某天你多次更改它,Git 刚好在 7*24*60*60 秒前;Git 在这里非常字面意思)。
还有很多其他方法可以找到提交,包括在提交 messages 中搜索文本。研究 the gitrevisions documentation 以获取更多命名提交的方法。
我有一个 master 分支,其中有几个月与 Web 项目相关的提交。
我有时需要通过浏览器查看网站在过去特定时间点的样子。
我目前checkout master分支,select时间点并创建了一个分支。然后我可以在那个时间点在浏览器中看到该站点。
我应该这样做还是有更简单的方法?
运行 git status
将为您提供分支的当前状态。暂存文件、未暂存修改文件、是否处于变基/合并等
为了在开发过程中持续查看站点,我建议使用本地服务器在本地为您提供站点服务,您可以在其中不断地 refresh
浏览器查看更改。
一种流行的方式(也用于 Github 页面)是通过 Jekyll 为网站提供服务。
您的方法是其中一种方法。 有几种方法可以更快地到达那里(一点点)。
如果您有某种网络 UI 可以查看存储库和相关提交(例如,如果您的存储库托管在 GitHub 或 BitBucket 上),您可以找出提交的 SHA1 散列并按散列执行结帐。命令将是:
git checkout <sha1>
如果您对相对于某个时间点的状态感兴趣,您可以使用一个简单的命令首先找到 "closest" 提交哈希,然后检查它。例如,如果您需要查看代码在 2017 年 3 月 1 日的状态,您实际上对发生在 03/01/2017 00:00 之前的最新提交感兴趣。命令将是:
git checkout `git rev-list -n 1 --before="2017-03-01 00:00" master
值得一提的是,如果您 运行 正在使用 Windows,则需要使用略有不同的语法。这是相同代码的 PowerShell 版本:
$sha = git rev-list -1 --before="2017-03-01 00:00" master git checkout $sha
最后,如果您知道某个提交代表了这些时间点之一,您以后会need/want回来,您可以使用Git稍后标记功能和结帐标签。例如,要标记提交,您可以 运行(将 sha1 替换为提交哈希 ):
git tag -a some-point-in-time <sha1>
当你想"come back"到这个时间点你可以运行:
git checkout -b master some-point-in-time
您可以在特定的早期提交处检出 master
分支,例如
git checkout <SHA-1 of some commit in master>
这将使您进入分离的 HEAD 状态。从这里,您可以实际构建您的项目、部署并查看它的外观。
如果您想从较早的提交创建一个真正的分支,您可以通过以下方式进行:
git checkout -b new_branch_from_old_commit
您很可能不需要创建新分支。环顾四周后,您可以 return 到您当前的 master
分支,只需检查一下即可:
git checkout master
您可以简单地 git checkout
通过哈希 ID 进行提交,尽管这听起来很可怕 "detached HEAD".
背景
分支和标签是命名某些特定提交的方式。就此而言,HEAD
只是一种命名分支的方式,或者有时是一个特定的提交。
因此:
git log
显示您从 HEAD
开始提交,并且:
git log master
显示您从 master
开始提交。如果HEAD
个名字master
,这两个做的事情完全一样。
添加--oneline
,或者我偏爱"DOG"—--decorate --oneline --graph
;还要考虑 "A DOG"、--all --decorate...
——稍微压缩输出:
* e0688e9 (HEAD -> master, origin/master, origin/HEAD) git svn: fix ...
* 3bc5322 First batch after 2.12
* 3e5c639 Merge branch 'rl/remote-allow-missing-branch-name-merge'
在这里我们看到 HEAD
名称 master
,还有两个提交名称 e0688e9
。
每个提交都会命名一个先前的提交(它的父提交)。这是如何 git log
能够显示多个提交。我们说分支和标签名称 指向 像 e0688e9
这样的提交,并且那个提交指向它的前身 3bc5322
,它又指向另一个,等等。
如果我们将这些绘制为一系列单字母名称提交(比 3bc5322...
哈希 ID 更实用),我们会得到如下所示的内容:
A <- B <- C <-- master
此处名称 master
指向 C
,C
指向 B
,B
指向 A
。 A
是有史以来第一次提交,所以它 不能 指向任何更远的地方,也不会。这就是 git log
知道 停止的方式!
分离头
通常,HEAD
包含实际的分支名称。在上面的 git log
输出中,我们看到 HEAD
名为 master
。正在做:
git checkout branch
告诉 Git 不仅要检查 branch
命名的特定提交,还要将 name branch
放入 HEAD
。我们说 HEAD attached 到分支。但是我们可以通过将原始哈希 ID 放入 HEAD
来 分离 它,我们通过 运行:
git checkout 3bc5322
这与在那里有一个分支名称的作用相同,除了 ...
新提交移动分支
当您进行 新 提交时,Git 将新提交写回当前提交,然后更改 当前分支 以便它指向新的提交。例如,如果我们添加一个新的提交 D
到我们的三提交 A-B-C
设置中,提交本身看起来像这样:
A <- B <- C <- D
但是 D
的名字是那些丑陋的大哈希 ID 之一,我们无法记住它。相反,我们让 Git 帮我们记住它——将它写入当前分支的名称。如果当前分支是 master
,这将更改 master
,使其不再指向 C
:
A <- B <- C <- D <-- master
现在master
为我们记住了D
,树枝本身也长大了!
但是,问题来了:Git 知道要更新哪个分支的方式是它存储在 HEAD
中。如果您有一个分离的 HEAD,则没有当前分支 name。在这种情况下,Git 将新提交 仅 记住为 HEAD
。假设我们添加 D
,同时我们通过哈希 ID 签出 B
:
A--B--C <-- master
\
D <-- HEAD
如果我们 git checkout master
,那会用名称 master
覆盖 HEAD
,"forgetting" 我们的新提交。
这并不是真的危险,除非它可能是:也许你写了一些非常棒的代码,你会 never be able to write again,但现在你已经失去了它,哦不!因此,为此目的,您可以在任何提交时 创建一个新的分支名称 , 包括 一个分离的 HEAD,使用 git checkout -b
:
git checkout -b newbranch
现在我们有:
A--B--C <-- master
\
D <-- newbranch (HEAD)
或者,当然,您可以给提交 B
一个标签,然后检查它,然后创建新的提交 D
。这里的要点是 commits 才是真正重要的;这些名称只是给我们 找到它们的方法。
命名提交的方式有很多种
您可以使用分支和标签名称,但您可以添加后缀和计数:
HEAD~1
例如表示"start at HEAD, but then walk back once to HEAD's parent"。 (如果提交是 merge commit——一个有多个父项——~
后缀选择 first 父项,每次.) 或者,您可以将 @{...}
与 HEAD
或分支名称一起使用:
master@{1.week.ago}
它使用 Git 调用 master
的 reflog 来查看哪个提交 master
恰好在一周前命名(如果那是某天你多次更改它,Git 刚好在 7*24*60*60 秒前;Git 在这里非常字面意思)。
还有很多其他方法可以找到提交,包括在提交 messages 中搜索文本。研究 the gitrevisions documentation 以获取更多命名提交的方法。