Git:直接进入工作目录的更改(链接到裸存储库)

时间:2018-06-03 19:10:27

标签: git

我在包含裸存储库的服务器上进行了设置,在将代码推送到工作目录时将其检出工作目录。

我必须直接在服务器上的工作目录中编辑一些文件。因此,这些更改不会提交到裸存储库中,我无法将它们提取到本地计算机。

这是我尝试过的(以及我没有尝试过的)

  1. 据我所知,提交不会对工作回购有效,因为它里面没有.git目录(这意味着因为它不是git init-ialized - 所以我不能做该
  2. 在裸仓库上执行提交命令不会在IMO上工作,因为我记得在SO上读到的东西,裸露的回购并不意味着直接提交。相反,您只需将代码推送给他们。您无法提交,因为他们没有提交代码。
  3. 我无法想到工作目录上的这些更改可以被识别为裸仓库中的提交。
  4. 我尝试在StackOverflow上搜索这个,但无法得到答案。也许没有使用正确的GIT术语,因为我只是在学习GIT。

2 个答案:

答案 0 :(得分:1)

DileepNimantha's answer大部分都是正确的(它至少在我写这篇文章时缺少一步),但有几种可能更容易的方法。我们以后会去最简单的一个;让我们从我们真正做的事情开始吧。我将补充说,缺少的步骤是在git fetch之后运行git read-treegit remote add ...(见下文)。还假设当前分支master是正确的。

根本问题是您已经确定的问题:您有一个裸存储库(core.bare = truegit init --bare等)因此没有工作树。

要在任何Git存储库中进行新提交,您在技术上根本不需要工作树。您需要的是与该存储库关联的索引(也称为登台区域或有时是缓存)以获得正确的文件内容。但是,执行此操作的标准方法是使用git add file1 file2 ...,它将工作树中的给定文件复制到索引中,覆盖索引中这些文件的旧版本。当然 需要一个工作树。

一个裸存储库,尽管没有工作树,但仍然有一个索引。以下是我们如何绕过缺乏工作树的方法。

您可以使用master从特定提交中填充索引,例如git read-tree的提示:

$ git read-tree master

然后,您可以从文件系统中的文件中替换其中一个索引条目。在这种情况下,我通过将sig.py解压缩到文件系统中现在位于/ tmp的文件中进行更新,然后在那里进行了编辑:

$ git hash-object -w -t blob /tmp/sig.py
b6a42a1dd3fff08aa4bed6b054b310f69ed518c1

现在需要为该文件生成git ls-files阶段条目。旧的是:

$ git ls-files --stage sig.py
100644 7e49ad4f1042b14e088571a091a7b9f7d1010b4c 0       sig.py

我们不需要使用舞台编号,因为git update-index允许我们跳过它,因此我们可以直接使用其他相关信息打印新哈希:

$ printf '%s %s %s\t%s\n' 100644 blob \
    b6a42a1dd3fff08aa4bed6b054b310f69ed518c1 sig.py | \
    git update-index --index-info

我把它分成三行,两行用反斜杠 - 换行符,用于发布篇幅。它实际上只是一个命令,但是当以这种方式表示为shell输入时,它也可以正常工作。请注意,新的blob哈希是通过将新的更新文件写入存储库而获得的。 (旁注:一旦我们开始这个过程,我们有大约14天完成我们的工作,在git gc声明我们新创建的blob对象未被使用之前,因此将其修剪。)

我们现在需要将索引编写为 tree 对象:

$ git write-tree
e92275076a62ca850b0bda3f6c3603632b4a6cce

然后将此树存储为提交对象。让我们在master的当前提示之后添加一个新提交:

$ git commit-tree -p master \
    -m 'make signal handler work in py2k and py3k' \
    e92275076a62ca850b0bda3f6c3603632b4a6cce

运行这个,对我来说,提交哈希:

e068bdfce2fd992dc396cb4969327ef5c4d39a43

我们现在需要创建一些分支名称,也许是一个新名称,引用此提交哈希。我会使用新的,而不是更新master

$ git branch fix-signal e068bdfce2fd992dc396cb4969327ef5c4d39a43

现在我们可以通过在这个裸存储库中运行git log来查看这是否有效:

$ git log --oneline --decorate -n 2 fix-signal
e068bdf (fix-signal) make signal handler work in py2k and py3k
11ae6ca (HEAD -> master) add run-checks script

让我们将更改视为补丁:

$ git show fix-signal
[snip]
index 7e49ad4..b6a42a1 100644
--- a/sig.py
+++ b/sig.py
@@ -5,7 +5,10 @@ import sys
 import time

 def signal_handler(signum, frame):
-    os.write(1, bytes('caught sig %d\n' % signum, 'iso8859-1'))
+    if str is not bytes:
+        os.write(1, bytes('caught sig %d\n' % signum, 'iso8859-1'))
+    else:
+        os.write(1, 'caught sig %d\n' % signum)

 def catch_by_sig():
     old_int = signal.signal(signal.SIGINT, signal_handler)

但这确实是一个--bare存储库:

$ git status
fatal: This operation must be run in a work tree

让它变得更容易

git前端命令会在动词之前显示之前的许多选项。例如,如果服务器上提取的工作树位于/tmp/work,则可以在服务器上cd到Git存储库:

$ cd ...

然后运行:

$ git --work-tree=/tmp/work status

并获取状态输出。 请注意git status将HEAD提交与当前索引内容进行比较,然后将当前索引内容与工作树进行比较。由于此处的主Git存储库是--bare存储库,它的索引可能根本不匹配/tmp/work目录的内容。 (根据您的服务器部署推送的方式,该Git存储库的索引可能是非空的。您必须决定是否关心其中的内容。)

如果需要,您可以使用git read-tree操作,就像我们在上面的较长形式中所做的那样,从某些特定提交中填充索引。您可以通过其分支名称命名提交,如上所述,或者通过其哈希ID命名:关键是从填充索引当前部署到部署区域的提交

现在索引填充的方式(主要是)匹配部署区域(修改后的文件除外),您可以运行:

git --work-tree=/tmp/work add file1.ext file2.ext
例如,要从工作树中添加这些文件(您将在" cd" -ed到Git存储库中)执行此操作。然后你可以运行:

git --work-tree=/tmp/work commit
像往常一样。 请注意,这将在当前分支上提交,,即HEAD在存储库中附加的分支。由于您正在使用的任何部署脚本,这可能是正确的。

基本上,每次运行Git命令时,都告诉它:忽略core.bare设置,在另一条路径中有一个工作树。实际上,&# 39; s可能是你的部署 - 推 - 操作钩子的工作原理。

我不建议按照正常做法进行此操作 - 您需要支付推送到非裸存储库的所有费用,但没有任何好处,所以您不妨设置一个非裸存储库,而不是做这种捣蛋。但作为紧急情况的快速破解,它可行。

答案 1 :(得分:0)

当然,您可以从工作目录中提交代码。您应该简单地将其作为git存储库启动。请尝试以下方法:

  1. False
  2. git init
  3. git remote add origin <your git url>您的更改并提交并推送到您的存储库。