14

我想做的事:在我的(ssh 远程访问)大学机器上,我从事一个项目,该项目已置于 git 源代码控制之下(git init然后git commit -a在每次更改后,一切正常)。现在我想在家里的私人机器上处理那个项目。应该很容易,因为 git 是分布式 vcs,对吧?

我阅读了git tutorial,它建议git pull在大学做一个以在家完成更改。那是行不通的,因为我家中的机器无法远程访问。所以我想我会git push在家里做一个。这行得通,但它很复杂(git reset之后需要在大学等),因为非裸存储库不是为推送而设计的

问题 1:有没有比在我的设置中添加额外的裸存储库更简单的方法(这意味着我有:(1)“主要”裸存储库,(2)大学工作副本,(3)家庭工作副本)?
<Rant>如果我真的需要那个设置,我可以留在 SVN。</Rant>

问题 2:如果确实需要该设置,我如何创建那个裸存储库(git clone --bare我猜)并使其成为“主”存储库,即告诉git push应该去那里的工作副本。

PS:我知道有一个 post-receive 钩子可以让你推入非裸存储库。我试过了,但效果不好,因为大学机器上的 git 版本很旧(1.5.5.6)并且错过了钩子使用的一些命令。更新不是一种选择,无论如何我更喜欢没有第三方脚本的解决方案。

4

3 回答 3

14

您真的不应该推送到已签出的分支,因为它有效地从远程工作副本下方拉出地毯。然后很难确定是否因为分支头已移动而修改了工作树,或者是否还有本地更改会被reset --hard.

最简单的做法是推送到不同的分支。然后,当您有权访问远程计算机并需要对其进行处理时,您可以将其合并到工作副本的结帐分支中(或将本地分支重新建立在其上)。

从家里:

git push origin HEAD:from-home

从工作':

git merge from-home

您可以将配置设置为默认为特定的推送 refspec。

例如

git config remote.origin.push +master:from-home

裸存储库通常更自然。您可以从现有存储库克隆它,或者像我通常做的那样,初始化一个新存储库并将我想要的主分支从现有存储库推送到它。

更好的是,如果您要在每个位置使用工作副本,则使用此技巧直接修改遥控器的遥控器,而不是专门重命名的分支。

因此,在起源上,创建一个名为“home”的远程 - 由于您的网络配置,您显然无法从中获取。那没关系。

在家里,告诉它,“当我推送到原点时,让它更新原点的远程命名为 home

git config remote.origin.push +master:home/master

现在,事情变得非常顺利。从 home 运行git push origin,然后转到 origin,然后运行git statusgit branch -a -v-- 你会看到类似于:“master 落后 home/master 3 次提交,并且可以快进。”

换句话说,使用 home 将更改推送到 origin 的远程命名 home,在功能上与使用 origin 从 home 拉取相同。

这里的一个缺点是,当您在家中创建额外的分支时,您需要不断地进行新的 git 配置设置。这是您为网络设置支付的开销。值得庆幸的是,它很简单,每个分支创建只发生一次。

于 2010-01-24T13:27:34.220 回答
1
  1. 这个问题总结了我尝试同步两个工作副本的经验。最终,我认为拥有一个裸存储库更加自然和简单。它不是 SVN 意义上的“主”存储库 - 例如,您可以在大学拥有一个,在家里拥有一个,并在它们之间进行推拉。

  2. 有人可能会发布将裸存储库设置为推送目标的正确方法,但不查看文档,我会简单地删除工作副本并再次从裸存储库克隆它。

于 2010-01-24T13:20:11.367 回答
1

我通过使用git-bundle解决了这个问题。在我的笔记本电脑上,我这样做git pull是为了获取上游更改。正如预期的那样,这适用于 ssh。然后,我git bundle将本地更改放入一个包中,将包文件复制到远程服务器,然后 ssh 到服务器并git pull从包文件中执行。

从文档中:

一些工作流要求将一台机器上的一个或多个开发分支复制到另一台机器上,但两台机器不能直接连接,因此无法使用交互式 Git 协议(git、ssh、http)。该命令提供对 git fetch 和 git pull 的支持,通过在源机器上将对象和引用打包到存档中,然后在通过某种方式(例如,通过sneakernet)移动存档后使用 git fetch 和 git pull 将它们导入另一个存储库. 由于存储库之间不存在直接连接,因此用户必须为目标存储库持有的捆绑包指定基础:捆绑包假定基础中的所有对象都已在目标存储库中。

我的存储库足够小,我可以使用--all. 但是,如果您的存储库更大,您可能只想将最近的更改添加到包中(例如,--since=10.days master获取最近 10 天的更改)。文档有更多示例。

这是我的代码。在这种情况下,膝上型电脑和服务器在同一个地方都有存储库:(~/src/这是一个非裸存储库,即工作副本)。~/tmp 目录同时存在于服务器和笔记本电脑上。

TMPDIR=~/tmp
cd ~/src
git pull $server:~/src/
git bundle create $TMPDIR/bundle --all
rsync $TMPDIR/bundle $server:$TMPDIR
ssh $server "cd ~/src;git pull $TMPDIR/bundle"
于 2019-08-31T06:28:54.067 回答