【问题标题】:Git pull from remote bare repositoryGit 从远程裸仓库拉取
【发布时间】:2017-06-21 12:20:18
【问题描述】:

当我尝试从裸露的远程存储库 pull 时,git 返回 Already up-to-date。

据我了解,如果本地存储库有一些更改,并且我提交它们从而推进HEAD,pull 不应该从裸远程存储库(其工作树已正确配置)并将它们与覆盖更改的本地合并?

如果本地存储库已更改并且这些更改已提交,那么推送当然可以工作 - 另一方面,拉取则不行。如果远程存储库发生更改并且我从中 pull、fetch --all 或 clone,我会收到相同的 up-to-date 消息或旧文件/以前推送的文件。

我做错了什么?

编辑,提供有关我想要做什么的更多信息。

我确实有一个本地存储库,其中包含两个文件,foo.c 和 foo.exe,以及一个配置了 post-receive 挂钩的裸远程存储库,用于将所有推送的文件放入工作树中。

发出git push remote master 后,我可以在工作树目录上看到foo.c 和foo.exe。如果在本地存储库上修改了这两个文件中的任何一个,git add . 和git commit -m "commit" 将跟踪修改后的文件,随后的git push remote master 将更新服务器上的文件。

如果在服务器上添加了foo.h,无论如何,我尝试git fetch remote master,git 说本地分支是最新的并且没有合并(它将获取的提交文件替换为本地的,是吗?)是必需的。怎么会这样?我需要先在远程存储库上提交更改吗?

【问题讨论】:

  • 您说“如果在服务器上添加了 foo.h”,但似乎您没有提交它(进入服务器的仓库),所以没有什么可以从服务器中提取(只能推送/提交)拉/取)。

标签: git version-control git-bare


【解决方案1】:

根据对问题的编辑进行了更新

...来自裸远程存储库(其工作树已正确配置)...

所以我理解这意味着您将存储库初始化为--bare,然后添加了worktree(更新配置以允许接收更新签出分支的推送),以便推送可以有效地部署您的可执行文件。

原来你说的

如果远程存储库发生更改并且我从中提取、获取 --all 或克隆,我会得到相同的最新消息或旧文件/以前推送的文件。

后来添加的

无论如何,如果在服务器上添加了 foo.h,并且我尝试 git fetch 远程 master,git 说本地分支是最新的并且没有合并(它将获取的提交文件替换为本地的提交文件,是吗?)是必需的。怎么会这样?我需要先在远程存储库上提交更改吗?

所以这里的问题是说“添加到远程存储库”是什么意思。

每个 repo(裸机或其他)的工作方式都是一样的。您将服务器存储库视为远程存储库,因为它在您的克隆中进行了配置,但在服务器上,它只是一个本地存储库,碰巧设置为以某种方式对推送做出反应。

所以您知道,如果您将文件放在本地工作树中,但您不添加和提交它,它就不会与其他存储库共享。在服务器上也是如此。将 foo.h 放在服务器上只是意味着工作树中有一个未跟踪的文件。 (并且您要小心服务器上的未跟踪更改;它们可能会在未来的推送尝试中造成混乱。)

push 和 fetch 操作在数据库之间共享引用和对象(提交及其依赖项)。这些操作不关心“发送方”工作树上的内容。除了可能避免破坏文件的保护措施外,他们也不太关心“接收方”工作树上的内容。

简而言之:是的,您必须在服务器上添加并提交文件,在分支上创建一个新的提交,然后工作站上的拉取才会得到任何东西。


我的原始答案中未包含在上述内容中的部分从这里继续:

如果本地存储库有一些更改,并且我提交它们从而推进 HEAD,则不应从裸远程存储库中提取不同的文件

更准确地说,pull 做了一个fetch 和一个“合并”,你问fetch 不应该从远程为merge 引入文件。答案是:只有在您之前的@​​987654329@/pull 之后它们发生了变化。消息“Already up-to-date”意味着除了你已经fetched 的那些之外,远程端没有任何变化,所以没有什么新东西可以合并。考虑:

远程包含一些提交

A --- B --- C <--(master)

你 clone 存储库,或 fetch 到现有的克隆,所以现在你有相同的;然后你做一些工作并提交它

A --- B --- C <--(origin/master)
             \
              D <--(master)

现在你是pull,这会导致fetch。但是fetch 不直接下载文件 - 它下载提交。您已经拥有源中的所有提交,因此无需下载;这很好,因为文件的历史记录(因为它们出现在原始位置)已经被考虑(从你 fetched C 首先开始)。

【讨论】:

  • 更新问题添加更多细节,谢谢!
  • 绝对清楚。我很感激!鉴于 worktree 与 repo 的路径不同,我将如何在服务器上添加和提交文件?
  • 假设它是用git worktree add ... 设置的,不同的路径将被自动处理。只需 add 和 commit 就像在工作站上一样
【解决方案2】:

git fetch/push 不对文件进行操作。他们对提交进行操作。远程上有一堆提交(它是否裸露都没有关系)。如果您在本地更改了一些文件并进行了提交,则本地存储库和远程存储库之间存在差异。

在您的情况下,您已经在本地拥有远程可用的所有提交,因此没有什么可获取的。这就是最新消息的原因。

如果你在这种情况下运行git status,你会得到一个信息,你在本地存储库中有一些更改没有共享到远程存储库:

On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

当您按照建议发布更改时,两个存储库 - 本地和远程 - 将具有相同的提交(假设没有其他人正在修改远程)所以,再一次,拉不会获取任何东西,ss 这些更改已经在本地可用.

但是,如果您在远程存储库中有一些提交,但在本地没有提交,情况会有所不同。

git fetch 将获取这些提交,但不会修改您工作区中的文件。要修改文件,您需要手动移动到新的提交。例如,通过运行git merge 命令 - 它会将新获取的更改合并到本地分支并将活动提交更改为本地分支的尖端之一。值得注意的是,merge 仅合并当前分支上尚不可用的更改。所以,如果你过去有一些提交并运行git merge old_commit_id,什么都不会发生。

git pull 的作用类似于 git fetch + git merge 用于当前分支。因此,如果远程有提交,它们将被获取。那么如果当前分支有来自远程分支的更改,但还没有在当前分支上,它们将被合并。

值得使用gitg 或gitk 工具来可视化提交图和分支标签,以便更好地了解内部发生的情况。

【讨论】:

  • "changeset" 在 git 中不是一个东西。 Fetch/push 对提交进行操作,提交是项目树的版本。最接近“变更集”的是可以在提交与其父级之间计算的补丁。这听起来可能有点迂腐,但这是我最近经常看到的一种误解,它会导致对如何使用该工具产生实际的误解。
  • @MarkAdelsberger 感谢您的纠正。我已经相应地更新了答案。
  • 如果fetch 和merge 对提交进行操作,那么是否也需要在远程存储库上提交更改?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 2021-05-27
  • 2019-06-29
  • 2013-09-22
  • 2011-11-26
  • 2011-10-06
相关资源
最近更新 更多