将现有的 Git 存储库推送到 Github 只会发送大约一半的提交?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/237408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:05:26  来源:igfitidea点击:

Pushing an existing Git repository to Github only sends about half the commits?

gitversion-controlgithub

提问by rpj

I have a local Git repository I've been developing under for a few days: it has eighteen commits so far. Tonight, I created a private Github repository I was hoping to push it to; however, when I did so, it only ended up pushing eight of the eighteen commits to Github. I deleted the Github repo and retried, with the same result.

我有一个本地 Git 存储库,我已经在其下开发了几天:到目前为止,它已经提交了 18 次。今晚,我创建了一个私人 Github 存储库,我希望将其推送到;然而,当我这样做时,它最终只将 18 个提交中的 8 个推送到 Github。我删除了 Github 存储库并重试,结果相同。

Any thoughts on why this might be happening? I've done this procedure before without a few times successfully, so I'm a bit stumped.

关于为什么会发生这种情况的任何想法?我以前做过这个程序没有几次成功,所以我有点难住。

Update: There is, and has always been, only the master branch in this repo. Just to address a few of the posted answers...

更新:这个 repo 中一直只有 master 分支。只是为了解决一些已发布的答案......

回答by farktronix

I took a look at the repository in question and here's what was going on:

我查看了有问题的存储库,这是发生了什么:

  • At some point, rpj had performed git checkout [commit id]. This pointed HEAD at a loose commit rather than a recognized branch. I believe this is the "dangling HEAD" problem that CesarB is referring to.
  • Not realizing this problem, he went on making changing and committing them, which bumped HEAD up every time. However, HEAD was just pointing at a dangling chain of commits, not at a recognized branch.
  • When he went to push his changes, git pushed everything up to the top of master, which was only about halfway through the current tree he was on.
  • Confusion ensued
  • 在某些时候,rpj 已经执行了git checkout [commit id]. 这将 HEAD 指向一个松散的提交,而不是一个公认的分支。我相信这是 CesarB 所指的“悬空 HEAD”问题。
  • 没有意识到这个问题,他继续进行更改和提交,每次都让 HEAD 抬起头。然而,HEAD 只是指向一个悬空的提交链,而不是一个公认的分支。
  • 当他去推送他的更改时,git 将所有内容都推送到 master 的顶部,这只是他所在的当前树的大约一半。
  • 混乱接踵而至

This diagram should make it more clear:

这张图应该更清楚:

                 -- D -- E -- F
                /             ^
   A -- B -- C -              |
   ^         ^               HEAD
   |         |
 remote    master

When he tried to push his changes, only Athrough Cwere pushed and remotemoved up to C. He couldn't get commits Dthrough Fto push because they aren't referenced by a known branch.

当他试图推送他的更改时,只有A通过C被推送并向上remote移动到C。他无法提交D通过F,因为它们不是由已知分支参考推。

Here's what you see when you're in this state:

当您处于这种状态时,您会看到以下内容:

$ git branch
* (no branch)
master

The solution is to move masterup to Fin the dangling chain of commits. Here's how I did it.

解决方案是在悬空的提交链中master向上移动F。这是我如何做到的。

  • Create a legitimate branch for the current state:

    git checkout -b tmp

    • The tmpbranch is now pointing at commit Fin the diagram above
  • Fast-forward masterto tmp

    git checkout master

    git merge tmp

    • masteris now pointing at commit F.
  • Throw away your temporary branch

    git branch -d tmp

  • You can happily push to the remote repository and it should send all of your changes.

  • 为当前状态创建一个合法的分支:

    git checkout -b tmp

    • tmp分支正指向在提交F上图中在
  • 快进mastertmp

    git checkout master

    git merge tmp

    • master现在指向 commit F
  • 扔掉你的临时分支

    git branch -d tmp

  • 您可以愉快地推送到远程存储库,它应该发送您的所有更改。

回答by Aristotle Pagaltzis

From Git 1.7.3 onwards, you can do this with one simple command:

从 Git 1.7.3 开始,您可以使用一个简单的命令执行此操作:

git checkout -B master

The -bswitch means “create branch here before checking it out” and -Bis the unconditional version of that, “even if the branch already exists – in that case, move it here before checking it out”.

-b开关的意思是“检查出来之前,在这里创建分支”,并-B是该无条件版本,“即使转移已经存在-在这种情况下,在这里检查出来之前移动它”。



A very simple approach for fixing this sort of problem is to just delete the masterbranch and recreate it. After all, branches in git are merely names for commits and the masterbranch is nothing special.

解决此类问题的一个非常简单的方法是删除master分支并重新创建它。毕竟,git 中的master分支只是提交的名称,分支没有什么特别之处。

So assuming that the current commit is the one you want masterto be, you simply do

因此,假设当前提交是您想要的提交master,您只需执行

git branch -D master

to delete the existing masterbranch, then do

删除现有master分支,然后执行

git checkout -b master

to a) create a new branch called masterthat points to the current commit and b) update HEADto point to the masterbranch. After that, HEADwill be attached to masterand therefore masterwill move forward whenever you commit.

a) 创建一个名为master指向当前提交的新分支和 b) 更新HEAD以指向该master分支。之后,HEAD将被附加到master,因此master无论何时提交都会前进。

回答by CesarB

Check if you are pushing the correct branches, and that the branches actually have what you think they have. In particular, check if you do not have a detached HEAD, which can be quite confusing if not done on purpose.

检查您是否正在推送正确的分支,并且这些分支实际上具有您认为的内容。特别是,检查您是否没有分离的 HEAD,如果不是故意这样做的,这可能会非常混乱。

The easiest way to check is to use gitk --all, which shows graphically all the branches, the HEAD, and more.

最简单的检查方法是使用gitk --all,它以图形方式显示所有分支、HEAD 等。

回答by Greg Hewgill

I suppose the first thing I would do would be to run git fsckon your local repository to make sure that it is all in good order.

我想我要做的第一件事就是git fsck在您的本地存储库上运行以确保它一切正常。

I've never seen this problem before, and I can't think of what might be wrong.

我以前从未见过这个问题,我想不出可能是什么问题。

回答by farktronix

I don't have the reputation to comment directly on CesarB's earlier answer, but gitk --alldoesn't work in this case because it only lists out known branches.

我没有直接评论 CesarB 早期答案的声誉,但gitk --all在这种情况下不起作用,因为它只列出了已知的分支。

gitk HEADshows this problem, but it's not entirely clear. The smoking gun is that mastershows up down the commit tree rather than at the most recent commit.

gitk HEAD显示了这个问题,但并不完全清楚。确凿的证据是master出现在提交树下而不是最近的提交。

回答by Matthew Maravillas

I've had this same problem twice, and finally figured out what I was doing that was causing it. In the process of editing an old commit with git rebase -i, instead of calling git commit --amend, I was calling git commit -aby force of habit, immediately followed by git rebase --continue, of course. Someone else might be able to explain what's going on behind the scenes, but it seems that the result is the detached HEAD problem.

我已经两次遇到同样的问题,终于弄清楚我在做什么导致它。在用 编辑旧提交的过程中,我没有调用git rebase -i,而是习惯性地git commit --amend调用,当然git commit -a,紧接着是git rebase --continue。其他人也许能够解释幕后发生的事情,但结果似乎是分离的 HEAD 问题。

回答by rpj

So, it turns out that both: the commit hash in .git/refs/heads/master was in correct and the information in .git/logs/refs/heads/master was incomplete; in that I mean it only went up to and included the commit hash specified in .git/refs/heads/master.

因此,事实证明:.git/refs/heads/master 中的提交哈希是正确的,而 .git/logs/refs/heads/master 中的信息不完整;我的意思是它只包含在 .git/refs/heads/master 中指定的提交哈希。

Once I fixed these files (by hand), and pushed back to Github, everything was gravy again. I still have no ideawhat happened to get things in this state, but I'm glad I've at least figured out the fix.

一旦我(手动)修复了这些文件,并将其推回 Github,一切又重新变得生动起来。我仍然不知道发生了什么事情使事情处于这种状态,但我很高兴我至少找到了解决办法。

In case anyone is wondering: to fix .git/refs/heads/master, I just replaced the content of that file with the latest commit hash (HEAD), and to fix .git/logs/refs/heads/master, I simply copied the contents of .git/logs/HEAD into .git/logs/refs/heads/master. Easy peasy... NOT.

如果有人想知道:要修复 .git/refs/heads/master,我只是用最新的提交哈希 (HEAD) 替换了该文件的内容,而要修复 .git/logs/refs/heads/master,我只是将 .git/logs/HEAD 的内容复制到 .git/logs/refs/heads/master 中。容易peasy...不是。