Git 从远程完全更新本地回购

Git 从远程完全更新本地回购,git,Git,我有一个小项目,我一直在两台不同的计算机上工作。我定期git推送到github(遥控器被称为origin),但有时在回到另一台计算机之前,我已经在一台计算机上工作了一周。当我回来的时候,我只想要一个完整的更新。所有的旧树枝都被修剪掉,所有的新树枝都被拔掉,等等 我可以完全删除本地项目,然后git cloneoriginrepo。这感觉很脏,但它不是一个大项目,所以需要几秒钟,基本上是用两个命令完成的 在git本身中是否有类似的快速简便的方法 我看到了,还有一些类似的答案,但所有的答案似乎要么使用

我有一个小项目,我一直在两台不同的计算机上工作。我定期
git推送
到github(遥控器被称为
origin
),但有时在回到另一台计算机之前,我已经在一台计算机上工作了一周。当我回来的时候,我只想要一个完整的更新。所有的旧树枝都被修剪掉,所有的新树枝都被拔掉,等等

我可以完全删除本地项目,然后
git clone
originrepo。这感觉很脏,但它不是一个大项目,所以需要几秒钟,基本上是用两个命令完成的

git
本身中是否有类似的快速简便的方法


我看到了,还有一些类似的答案,但所有的答案似乎要么使用脚本,要么在分支基础上工作,这比我认为可能的要复杂一些。

因此,如果我正确理解您的问题,您可以使用:

git fetch [remote]
从远程分支获取更改,但不更新跟踪分支;或

git fetch --prune [remote]
要删除已从远程存储库中删除的引用,请执行以下操作

还应研究:

git pull [remote]

从远程获取更改并将当前分支与其上游合并。

这里要记住的是“分支”——更具体地说,分支名称对Git来说并没有任何意义。它们对您来说很重要,但就Git而言,每个名称只是查找一个特定提交的方法。Git真正关心的是存储库中的提交

每个提交都有自己独特的大哈希ID。例如,您可以在
git log
输出中看到这些ID。Git的真正魔力在于,任何地方的每个Git存储库都会同意,如果您或他们存储库中的一个特定提交具有某个哈希ID H,那么任何地方的其他提交都不会具有该哈希ID。1因此,当两个Git存储库“相遇”时,通过
Git fetch
Git push
,它们只需要比较哈希ID。您的GitHub存储库位于GitHub上,在其名称
master
下列出了一些commit和一些hash ID H。你的Git调用他们的Git。他们的Git显示:我的名字
master
对应于hash ID H。你的Git检查:我有H吗?如果你的Git已经有了H,那么它就完成了。如果没有,您的Git会要求他们的Git发送commit H

你自己的Git有你自己的名字。其中一个可能是
master
。它有一些散列ID。不管您的
主机在这里有什么散列ID,对于
获取操作来说,对您的Git来说唯一重要的是:我有提交H吗?您的Git始终可以通过原始哈希ID直接查找其所有内部Git对象。您可能已经有了H,也可能没有。因为任何地方的Git都不能将哈希ID H用于除此提交之外的任何内容,所以Git所要做的就是检查这一点

如果你根本没有H,你的Git会让他们的Git发送提交H。现在,关于每个提交的另一件事是:每个提交记录一些父提交哈希ID集。提交的父级或父级是“就在”该提交之前的提交(或对于合并,两个或多个提交)。也就是说,给定一长串提交,一次提交一个,每个提交都将前一个comit的哈希ID存储在向后指向的链中:

... <-F <-G <-H
(字母代表真正的散列ID,看起来完全随机,但实际上是完全确定的)。给定最后一次提交的ID
H
,我们只需要Git查找
H
。在
H
中,Git找到hash ID
G
,这样它就可以查找
G
。在
G
中,Git找到hash ID
F
,这样它就可以查找
F
,依此类推。这让Git可以从最后一次提交一直向后到第一次提交

这甚至可以在存在分支提交结构的情况下工作:

          I--J
         /
...--G--H
         \
          K--L
现在有两个最后的提交
J
是一个结构中的最后一个提交,而
L
是另一个结构中的最后一个提交。我们应该将这两个结构称为分支吗?——它们在返回到
H
时相遇,然后它们在返回到时间开始时共享提交(可能是提交
A

在一个真正的存储库中,我们可能有数千或数百万次提交。有一大堆旧的散列ID。您或Git如何快速找到最后一次提交?在维护命令中,Git会列出每个提交,并找出哪些是“最后一个”。这需要一段时间:几秒钟,或者在非常大的存储库中,有时需要几分钟。这显然太慢了。另外,谁想使用散列ID?人类当然不会

因此,Git为我们提供了使用名称来记住一(1)个散列ID的能力。我们可以选择名称
branch1
来记住散列ID
J
,选择名称
branch2
来记住散列ID
L

          I--J   <-- branch1
         /
...--G--H
         \
          K--L   <-- branch2
          I--J   <-- origin/master
         /
...--G--H   <-- master
         \
          K--L   <-- origin/develop
H
之后是否有提交并不重要
H
master
中的最后一次提交。这就是分支的全部定义。就是这样:在Git中,分支名称只是一个指针;这只是一种保存一个散列ID的方法,根据定义,无论名称保存的是什么散列ID,这都是该分支中的最后一次提交。2

因此分支
branch1
在提交
J
处结束,并自动包含通过从
J
开始并向后操作可以获得的每个提交。分支
branch2
在提交
L
时结束,并包括
L
之前的所有提交,Git再次向后工作。Git总是反向工作。如果出于某种原因它需要向前工作,那么它首先向后工作并在执行时记住散列ID,然后在记住的列表中向前工作。而且,提交可以而且经常在多个分支上进行

当你的Git对你来说是新的时,从他们的Git提交,你的Git
          I--J   <-- branch1
         /
...--G--H   <-- master
         \
          K--L   <-- branch2
...--G--H   <-- master, origin/master
          I--J   <-- origin/master
         /
...--G--H   <-- master
         \
          K--L   <-- origin/develop
          I--J   <-- origin/master
         /
...--G--H   <-- master (HEAD)
         \
          K--L   <-- origin/develop
git merge --ff-only origin/master
          I--J   <-- master (HEAD), origin/master
         /
...--G--H
         \
          K--L   <-- origin/develop
...--G--H   <-- branch (HEAD)
...--G--H   <-- branch (HEAD)
         \
          I
...--G--H
         \
          I   <-- branch (HEAD)
...--G--H--I--J   <-- master (HEAD), origin/master
         \
          K--L   <-- origin/develop
...--G--H--I--J   <-- master (HEAD), origin/master
         \
          K--L   [abandoned]
git config --global fetch.prune true
...--G--H--I--J   <-- master (HEAD), origin/master
         \
          K--L   <-- origin/develop
...--G--H--I--J   <-- master, origin/master
         \
          K--L   <-- develop (HEAD), origin/develop
...--G--H--I--J   <-- master, origin/master
         \
          K--L   <-- origin/develop
              \
               M--N   <-- develop (HEAD)
...--G--H--I--J   <-- master, origin/master
         \
          K--L
              \
               M--N   <-- develop (HEAD), origin/develop
...--G--H--I--J   <-- master (HEAD), origin/master
         \
          K--L--M--N   <-- origin/develop
...--G--H--I--J   <-- master (HEAD), origin/master
         \
          K--L--M--N--O   <-- origin/develop
...--G--H--I--J   <-- master, origin/master
         \
          K--L--M--N--O   <-- develop (HEAD), origin/develop
...--G--H--I--J   <-- master (HEAD), origin/master
         \
          K--L--M--N--O   <-- origin/develop
...--G--H--I--J   <-- master (HEAD), origin/master
         \
          K--L--M--N--O--P   <-- origin/develop
...--G--H--I--J   <-- master, origin/master
         \
          K--L--M--N--O--P   <-- HEAD, origin/develop
...--G--H--I--J   <-- master, origin/master
         \
          K--L--M--N--O--P   <-- origin/develop
                          \
                           Q   <-- HEAD
git checkout -b feature
...--G--H--I--J   <-- master, origin/master
         \
          K--L--M--N--O--P   <-- origin/develop
                          \
                           Q   <-- feature (HEAD)