术语
首先,让我们弄清楚一些术语...
upstream <= 远程 git 仓库(通常是生产环境中主分支或发行版分支所在的仓库)
forked-repo <= 远程 [实验性 git 仓库] (https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) ,也称为“origin”。
local repo <= 您在本地工作站上使用的文件和目录,您可能通过运行 git clone my-forked-repo.git
命令获取了这些文件。
local index <= 也称为本地 git “stage”,即您将文件推送到远程仓库之前的暂存区。
Github 工作流程
接下来,让我们谈谈将更改提交到 upstream 仓库的过程:
通常的过程是在功能分支上工作,然后将该分支推送并打开一个 Pull Request,将其合并到 forked-repo 的master分支或 upstream 的master分支中。
通过运行git checkout -b FEATURE_BRANCH_NAME
创建一个功能分支。
添加/删除/修改项目文件。
通过运行git add .
添加文件。
通过运行git commit -m'My commit message'
将您的文件提交到暂存区。
通过运行git push origin FEATURE_BRANCH_NAME
推送您的暂存区文件。
完全不同的提交历史记录的解决方案
当您 fork 了一个 git 仓库并更改了 git 历史记录时,可能会出现“master 和 upstreambranch 是完全不同的提交历史记录”的消息。
例如,如果你 fork 了一个仓库并将其拉到本地进行工作...
如果然后您决定重写整个应用程序,并决定删除所有现有文件,包括 forked-repo 的 .git 目录。您添加新文件和目录来重新创建应用程序,并使用 git init
命令重新创建 .git 目录。
现在,您的应用程序使用新文件运行良好,您想将其合并到 upstream 仓库中。但是,当您推送更改时,您会收到“...完全不同的提交历史记录...”错误消息。
你会发现你在新的本地目录和远程分支(my-forked-repo)上原始的git提交记录是不同的。可以通过在当前目录运行以下命令来检查:
git log --reverse master
,然后运行以下命令:
pushd $(mktemp -d); git clone https://github.com/my-forking-username/my-forked-repo.git; git log --reverse master; popd
。
如果你想提交你的更改并进行拉取请求(以期将你的新更新合并到upstream/master分支),则必须修复本地.git仓库,使其与远程的my-forked-repo相匹配。
git clone https://github.com/my-forking-username/my-forked-repo.git
cd my-forked-repo
git checkout -b my-new-files-branch-name
# Delete all files and directories except for the .git directory
git add .
git commit -m'Remove old files'
# Copy your new files to this my-forked-repo directory
git add .
git commit -m'Add new files'
git push origin my-new-files-branch-name
在 GitHub 上创建一个 PR,请求将您的 my-new-files-branch-name 分支合并到 master 中的 my-forked-repo 中。
注:对于相同原因,非 forked 的 repo 也可能出现“完全不同的提交历史记录”错误消息,并且可以使用上述相同的解决方案进行修复。
git subtree split
命令来提取子树中所做的更改,将分支推送到原始子树所在的远程仓库,但现在我无法将更改合并到该仓库中任何现有的分支中。不确定如何继续操作。 - yoyo