GIT:如何将现有的远程分支与现有的本地目录同步

3

所以,我有一个本地目录,这是一个非常简单的例子:

repo/
  foo/
    bar.txt (newer version)
    somefile.txt
    ...
    anotherfile.txt

同时我还有一个远程代码仓库,就像这样

repo/
  foo/
    bar.txt (older version)
    importantfile.txt
    

这些文件夹从未同步过。
我想同步已存在于远程仓库的文件(如上例中的 bar.txt 和 importantfile.txt)。
因此,问题在于如果我执行以下操作:
git init
git git remote add origin [url]
git fetch origin
git add .

然后使用git add命令提交所有本地文件,但我想跟踪已经存在于远程的文件。

已经尝试在其他主题中找到任何解决方案,但没有成功。

请帮忙。 P.S. 我是一个git新手。


"跟踪已存在于远程的文件", git fetch 会自动完成此操作。还需要什么? - phd
在执行 git fetch 后,本地文件夹 foo 仍然处于“未跟踪”状态。@phd - igolka97
3个回答

1
据我所了解,您正在寻找git add -u (git add --update)命令。
这将更新索引(意味着那些已经在远程的文件将被更新)。
重要提示:备份本地和远程存储库,因为这将更新索引。
然后,您需要:
  • 进入一个临时文件夹
  • 执行git clone <your-remote-repp-url>
  • 复制新创建克隆的 .git 目录
  • 用复制的 .git 目录替换本地目录中的 .git 目录
  • 然后从本地目录执行 git add -u
  • 最后执行git commitgit push

0

git add . 告诉 git 将当前文件夹中的所有内容都添加(暂存)。

这通常不是 git 的使用方式。大多数情况下,您实际上会选择哪些更改应该进入下一个提交。 git add bar.txt 只会将单个文件加入暂存区。

您也可以使用 git add bar.txt importantfile.txt 来加入多个文件。

git add -u . 会将所有已更改且已被跟踪的文件都加入暂存区。

编辑:实际上,git 并不关心同步文件夹。您随时可以删除所有内容并重新编写文件。在 git 中,提交始终是您暂存的完整文件的快照,而不是更改集。

编辑2:抱歉我之前没有注意到,但您的工作流程仍然让主分支指向空白。这在我的端上可以正常工作。

git init
git git remote add origin [url]
git fetch origin
git reset origin/master
git add -u

我在远程有大约1万个文件,在本地更多。手动添加每个文件是不可能的。 - igolka97
我不知道你在做什么。但是有10k个文件,我猜你不是手写它们的。通常生成的文件不适合添加到git中。Git有其限制,可能有更好的解决方案适用于您的用例。否则,git add -u .将执行您要求的操作。 - ian
根据git文档,-u应该添加所有已跟踪的文件。你尝试过不带文件夹使用git add -u吗? - ian
我刚刚注意到,在git init && fetch之后,我忘记了检出分支。如果使用git checkout origin/master && git add -u,则文件将被跟踪,但我会失去所有本地更改。我还尝试过git checkout -b update && git add -u,但foo文件夹仍未被跟踪。我做错了什么? - igolka97
只有使用 git reset 命令并带上 --hard 标志才能覆盖您的工作目录。 - ian
显示剩余4条评论

0

好的,我认为你已经在正确的轨道上了。这是我认为它应该如何工作的方法。

建议:在尝试此操作之前,请备份!

您可以从存放所有文件的目录开始。清理目录是个好主意(这样就不会有你不感兴趣的文件),但这并非必须。

然后:

git init .
git add .
git commit -m "my files"
git remote add rmt <URL to remote repository>
git fetch rmt
git branch -r    // look at the remote branches
git merge -Xours --allow-unrelated-histories  rmt/master

这里是对此操作的简短解释。

  • 前三个命令(包括git commit):将所有本地文件放入您自己的本地git存储库中
  • 接下来两个命令(包括git fetch):告诉git您的远程存储库在哪里并获取内容;在此示例中,我称其为“rmt”;您可以选择任何名称。只是我的建议:不要将其命名为“origin”;因为这个名称通常保留给您从中克隆自己的本地存储库的存储库。但这不是您在这里做的事情。
  • git branch -r 这是为了了解名为“rmt”的远程存储库上有哪些分支。在下一行中,我假设您对远程存储库上的“master”分支感兴趣
  • git merge 现在就来了魔法 :-)

这里重要的部分是merge的选项:

  • -Xours 告诉 git 不要用远程仓库的文件覆盖你的任何文件。这样可以确保你已经存在的文件不受影响。从描述中我不能百分之百确定这是否符合你的需求。如果你省略此选项,那么 git 将尝试合并具有不同内容的文件;但这可能会有问题。(如果你想在这里使用其他策略,请阅读 git 合并策略)。
  • --allow-unrelated-histories 这里有一些你必须理解的东西:这种方式意味着,你的仓库目前与远程仓库完全没有关系。为了理解这一点:git 存储目录的快照。你创建了一个目录的快照(使用前三个命令)。远程仓库中也有另一个目录的快照,你使用 git fetch 将其复制到自己的仓库中。除了快照外,git 还存储历史记录,即它记住哪个快照是由哪些其他快照生成的;这些是快照的“祖先”。但是你的快照是一个“初始”快照,没有任何祖先。因此,它与远程仓库中的任何其他快照都没有关联。当然,根据你的描述,我猜想你在某个时候复制了远程仓库,但至少 git 不知道这一点。结果是,git通常不会接受合并这两个快照,因为在 git 的视图中,这两个快照完全没有关系。使用此选项,你告诉 git 忽略这个不相关的历史记录,并仅合并这两个快照。

接下来你可以查看一下使用 git log 命令所得到的结果。你应该会看到类似于以下内容:

commit ... (HEAD -> master)
Merge: ... ...
Author: ...
Date:   Sat Dec 5 02:08:55 2020 +0100

    Merge remote-tracking branch 'rmt/master'

commit ...
Author: ...
Date:   Sat Dec 5 02:03:24 2020 +0100

    my files

你可以使用git show HEAD命令查看添加了哪些文件。

你可以使用git diff rmt/master..HEAD命令比较你的快照和远程分支之间的差异。这将显示在合并后,你需要更改“rmt/master”中的内容才能到达你的快照。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接