Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 是否可以在维护历史记录的同时,在远程上进行与本地repo内容匹配的新提交_Git - Fatal编程技术网

Git 是否可以在维护历史记录的同时,在远程上进行与本地repo内容匹配的新提交

Git 是否可以在维护历史记录的同时,在远程上进行与本地repo内容匹配的新提交,git,Git,我的用例有点奇怪。我是按程序进行的,没有重置软/混合和合并的权限 我在本地机器上有回购协议。我在本地做了一些文件更改,但没有提交。有权访问同一回购协议的其他人也进行了更改,并将其推到远程。我希望本地目录中的文件内容成为远程目录的头。我基本上想强制推送,但要在远程服务器上保持现有的历史记录。希望通过一个例子说明: Repo A: file1.txt file2.txt Commits: "Init repo" 我和person 2都克隆了回购A。person 2进行了一些

我的用例有点奇怪。我是按程序进行的,没有重置软/混合和合并的权限

我在本地机器上有回购协议。我在本地做了一些文件更改,但没有提交。有权访问同一回购协议的其他人也进行了更改,并将其推到远程。我希望本地目录中的文件内容成为远程目录的头。我基本上想强制推送,但要在远程服务器上保持现有的历史记录。希望通过一个例子说明:

Repo A:
    file1.txt
    file2.txt
Commits:
    "Init repo"
我和person 2都克隆了回购A。person 2进行了一些更改并推送它们。远程回购现在如下所示:

Repo A:
    file1.txt
    file3.txt
Commits:
    "add file3"
    "rm file2"
    "Init repo"
Repo A:
    file1.txt
    file2.txt
    fileA.txt
Commits:
    "Init repo"
Repo A:
    file1.txt
    file2.txt
    fileA.txt
Commits:
    "did my own thing"
    "add file3"
    "rm file2"
    "Init repo"
在我的本地回购协议上,我做了一些工作。现在,我的本地回购协议如下所示:

Repo A:
    file1.txt
    file3.txt
Commits:
    "add file3"
    "rm file2"
    "Init repo"
Repo A:
    file1.txt
    file2.txt
    fileA.txt
Commits:
    "Init repo"
Repo A:
    file1.txt
    file2.txt
    fileA.txt
Commits:
    "did my own thing"
    "add file3"
    "rm file2"
    "Init repo"
我想进行提交和推送,使远程设备看起来像这样:

Repo A:
    file1.txt
    file3.txt
Commits:
    "add file3"
    "rm file2"
    "Init repo"
Repo A:
    file1.txt
    file2.txt
    fileA.txt
Commits:
    "Init repo"
Repo A:
    file1.txt
    file2.txt
    fileA.txt
Commits:
    "did my own thing"
    "add file3"
    "rm file2"
    "Init repo"
我刚刚做了一个新的提交,文件内容与我的本地目录完全匹配。我不想合并或诸如此类的事情。但重要的是,历史得以保持


这可能吗?我相信这可以通过软重置来完成,但我没有访问权限。另一个选项是将repo A克隆到另一个文件夹,删除内容并复制到我的本地文件上。不过这太慢了。还有其他方法吗?

请这样做。它应该会起作用。我正常使用它,它会重新设置基址

git-pull——重基


请吧。它应该会起作用。我正常使用它,它会重新设置基址

git-pull——重基


您要求做一件奇怪的事情,可能应该改为使用rebase(我看到您已经接受了这一答案)。但是使用rebase并不能完成您要求的奇怪任务

在这些限制范围内,不可能按照所描述的方式执行此操作。此外,您给出的描述具有误导性,因为存储库不包含文件;存储库包含提交。提交然后表示满是文件的树,但在您告诉Git提取某些特定的提交之前,您只有一系列的提交

如果你能放松你的限制,你就能做到。我将在下面描述如何以及为什么

Git做什么 当您有两个或多个存储库时,就像这里的情况一样,每个存储库都有自己的提交集合,有自己的分支名称,如
master
,并且有自己的概念,即每个分支名称的“提示最新”(如果您愿意,最新)提交。在这种特殊情况下,涉及三个独立的存储库:

  • 位于
    原点的
    ,您称之为“回购A”
  • 你的
  • 第二个人的
您通过使用
git clone
让您的计算机在
origin
上调用另一个git,并将整个存储库的所有提交复制到您自己的存储库中,完成了最后一个操作。您的Git获取了它们的分支名称,如
master
,并将它们重命名为远程跟踪名称,如
origin/master
。最后,您的
git clone
运行了
git checkout master
,它让您的git创建您自己的master,并将其设置为指向commit by hash ID:与他们为
master
列出的hash ID相同,您现在正在调用
origin/master

git checkout
还填充了您的索引和工作树。索引是让Git构建下一次提交的地方,这就是为什么在Git中总是要运行
Git add
。您的工作树是您实际查看文件的位置。它们与您自己的Git存储库相关联,但实际上并不是存储库的一部分,这与索引不同,索引在提交(永久且不可更改)和工作树(您在其中执行工作,并因此实际更改内容)之间占据了一种模糊的位置

当然,Person 2也会执行相同的
git克隆
,这将创建存储库的副本,然后他们的
git签出
创建他们的
master
,并填写他们的索引和工作树

现在,关于任何存储库中的提交,都有许多有趣的事情。一种是这种(大部分)永久和(完全)不可改变的”财产。另一个原因是,每次提交都会存储与该提交相关的所有文件的快照。这就是在您
git checkout
该特定提交时获取这些文件的原因

一个关键的、相当神奇的属性是,每个提交都有一个保证唯一的散列ID,如
7668cbc6057f99a4c048f8f8f3877930b8147b
。当我说“唯一”时,我真正的意思是“唯一”:无论存储库存在多少副本,
7668cbc6057f99a4c048f8f8787930b8147b
在每个副本中都是相同的提交。它要么在那里,要么不在那里,这取决于你是否捡起并保存了它(如果是别人做的),或者是你自己做的(如果你要做的话)

最后一个关键点是,每次提交都可以存储上一次提交或父提交的哈希ID。正是这些散列ID,加上像
master
这样的分支名称存储了最近的一个,才产生了历史记录。Git总是以最近的提交开始,通过在分支名称(如
master
)下找到的散列ID,并使用它。然后,如果您想回顾历史,Git会找到提交的父ID,并查看父提交中的文件。父项有另一个父项,即当前提交的祖父母,该父项还有另一组文件;等等

每当任何Git中的任何人进行新提交时,Git所做的就是将当前提交保存为父ID,并为新提交构造一个新的、唯一的(世界各地)哈希ID:

... <-hash  <-hash  <-tip   <-- master
现在要使用您的工作树构建一个新的提交,但要在Person 2的最新提交之上构建它,您需要
git reset--soft
。这允许您移动当前分支名称
master
,以便它指向