我计划将GitHub存储库中的某个文件夹路径提取到新存储库。例如:
- repository/
- src/
- primaryCode/
- codeToExtract/
- ci/
- ...
我要将codeToExtract
迁移到新的存储库。
是否可以找到对该文件夹进行了更改的分支?这是一个团队项目,因此不能手动检查它们。
答案 0 :(得分:3)
git for-each-ref --format='%(refname)' refs/heads/ |
while read branch; do
if test -n "`git rev-list -n1 $branch -- $path`"; then
echo $branch
fi
done
说明:
git for-each-ref --format='%(refname)' refs/heads/ — list all branches
while read branch — run the loop over every branch
git rev-list -n1 $branch -- $path — find a commit in the branch
that touches the $path
if test -n … echo $branch — if at least one commit found print the branch name.
答案 1 :(得分:0)
问题格式错误,但是一旦确定格式, answer 可能是肯定的。但是,哪个是,以及您想要哪个答案,取决于您的真实意思。
每个提交都保存一个快照。没有提交保存更改 ,就像您拥有多张照片(也许您的年龄不同)一样,没有任何照片保存任何更改。但是也许一张照片中的头发比另一张照片中的头发更长(或更多),所以通过比较两张照片,您可以观察更改。
您现在可能已经看到的问题是,您必须选择两个快照。您在乎哪两个?您可以选择任意两个,但只能选择两个,或者一次选择两个。
Git 关心的是各种提交。就像我们刚才说的那样,每个快照都有一个快照,但是还包含更多快照。例如,它包含创建快照的人的姓名和电子邮件地址。它具有一个日期和时间戳。 (实际上,它同时具有 author 和 committer ,并提供两个名称,电子邮件地址和时间戳。)它有一条日志消息,由提交该内容的人写告诉你为什么他们做出了这个承诺。并且,每个提交都存储其 parent 提交(或在合并提交的情况下为提交)的哈希ID。这些额外的东西是用于提交的元数据,主要数据是源快照。
每个提交都有自己唯一的哈希ID。这个散列ID似乎是随机的,实际上只是该提交内容(数据+元数据)的加密校验和。该哈希ID是Git实际查找提交的方式-它如何从Git存储的主数据库中检索提交的内容(数据+元数据)。您已经在git log
输出中看到了这些哈希ID,并且到处都有缩写版本-Git迫切需要它们,因为它们是内部Git对象的实际名称,因此Git不可避免地会向您显示其中的一些。例如,它们看起来像b5101f929789889c2e536d915698f58d5c5c6b7a
。但是,它们对人类来说毫无用处:它们太难记了;我必须剪切并粘贴它们才能使其正确。
给定任何一个特定的提交哈希ID,Git可以找出提交及其元数据。该元数据包含提交的父提交哈希ID,因此Git现在也可以探出父提交。然后,Git可以比较两个提交,这就是您所看到的,例如git log -p
输出:此比较的结果。与该提交的父提交相比,git log
和git show
都将完整快照减少为一组更改。这就是两个快照的来源。
现在,因为提交具有其父级的哈希ID,又有另一个其父级的哈希ID,依此类推,我们可以将提交绘制为一系列向后指向的节点,每个节点代表提交,箭头从该节点发出作为父节点的哈希ID:
... <-o <-o <-o ...
但是要开始此过程,我们必须知道一些起始点(结束点)哈希ID。我们可以写下那些大的丑陋的哈希ID,或者将它们剪切并粘贴很多,但是我们有一台计算机。为什么计算机没有为我们保存哈希ID?这是分支名称出现的地方。
实际上,分支名称是存储一(1)个哈希ID的地方。我们将 last 提交的哈希ID存储在分支上:
...--F--G--H <-- master (HEAD)
(在这里,我使用了H
之类的大写字母来代替实际的散列,只是为了使它们更易于讨论。)要进行 new 提交,我们必须提在我们的工作树中使用源代码,使用git add
告诉Git更新其准备好快照的文件副本,然后使用git commit
收集元数据并制作新快照。这将获得一个新的,不可预测的哈希ID。请记住,输入之一是 time ,因此,即使我们预测了源,名称和日志消息等等,在按Enter或Enter键之前,我们都不知道哈希ID是什么。点击“提交”按钮。
无论如何,我们都会得到一个带有新哈希ID的新提交,我们可以仅调用I
:
...--F--G--H <-- master (HEAD)
\
I
I
的父母是H
。现在出现了一个狡猾但精通的技巧:Git将提交I
的实际哈希ID写入当前的分支名称 master
中。我们可以像现在这样拉直我们的图纸:
...--F--G--H--I <-- master (HEAD)
我们有一个新快照,其父对象是旧快照。
如果我们现在创建一个新分支,则会得到两个名称,它们指向提交I
:
...--F--G--H--I <-- feature, master (HEAD)
请注意,所有提交都在两个分支上。我们可以使用HEAD
来切换哪个分支具有git checkout feature
的分支:>
...--F--G--H--I <-- feature (HEAD), master
现在,如果我们进行新的提交J
,它将在feature
上仅 :
...--F--G--H--I <-- master
\
J <-- feature
我要将codeToExtract迁移到新的存储库。
假设您的意思是打算从某些提交中取出名称位于该目录/文件夹中的文件,并将其放入新的存储库中。到目前为止一切顺利。
是否可以找到对该文件夹进行了更改的分支?
您现在知道,分支和提交都没有更改,但是分支确实允许您查找提交,如果您选择任何两个特定的快照(提交),您可以比较它们。
请记住,某些提交可能在许多分支上。如果有的话,这取决于您要执行的操作。您还可以决定是将检查的每个提交与其父级进行比较,还是与某个固定的起点或终点提交快照进行比较。例如,您可能有一个包含以下内容的图形:
o--o--*--K
/ \
...--o--*--o--*--L---M--o <-- br1
\
o--*--o--o <-- br2
每个*
提交所具有的位置(与它的父提交相比)在所讨论的一个文件夹中的文件中有些差异。
您还需要决定如何处理合并提交。这些是具有多个父项的提交。我给了字母M
上方一个有趣的合并提交,并给了它的两个 父母中的每个字母K
和L
(尽管实际上它们都会有丑陋的哈希ID)。像其他任何提交一样,合并提交M
具有快照。但是很难将其与其父级进行比较,因为它没有一个父级,它具有两个父级。
由您自己决定如何处理。如果您决定分别从*
和K
的两个L
提交中提取文件,则可能要从M
提交中提取文件同样,即使这些文件与K
和/或L
中的文件匹配。
您可能根本不关心其中的任何一个:也许您只想查看 each 分支的 tip 提交,然后将每个比较以其他所有此类技巧都致力于找出您想要的一个文件夹中文件的哪个版本。如果您要这样做,则可以使用git diff
进行以下比较:给git diff
提供两个提交哈希ID,它将比较这两个提交中的快照。给它两个分支名称,例如master
和feature
,或br1
和br2
,它将比较由这些名称标识的两次提交的快照,而不做任何父操作-link-following。
弄清楚想要的答案或想要回答的问题后,就可以使用它来获取想要的东西。
答案 2 :(得分:0)
只需执行以下操作即可代替单独的搜索:
git clone -ns . ../extract
cd $_
git filter-branch \
--subdirectory-filter src/codeToExtract \
-- --all -- src/codeToExtract
上方的第二组参数(在第一个--
之后)是您要使用的分支,第三组参数(在第二个--
之后)是您关心的路径。
然后(一如既往,Git不在乎存储库边界或名称本身,它们只是方便,仅历史记录很重要),以所需的任何名称将所需的任何历史记录推入/获取到您想要的任何存储库中。 / p>