您好我是一个使用git的新手我在这个错误上阅读了一些StackOverflow Q& A但是我并不了解我的问题与其他人有相同的错误信息。所以我没有机会把它放松,而且我需要将6小时的工作放到我的远程GitHub仓库中。
1。)开头
所以我在本地工作目录中的代码被破坏了,我无法弄清问题是什么。所以我希望git回到我项目的最新工作版本。然后我找到了这个教程并设法让我的本地项目回到工作版本。 https://www.git-tower.com/learn/git/faq/restore-repo-to-previous-revision
$ git reset --hard <SHA-1 HASH NUMBERS>
2.尝试推送
当我想将本地代码推送到我的远程仓库时,这些是我经常遵循的命令。
# Pushing Changes - Staging
$ git diff
$ git status
$ git add -A
$ git status
$ git commit -m "Modified multiply function."
# Pushing Changes - Repository
$ git pull origin master
$ git push origin master
3。)错误
我不明白错误消息试图告诉我的内容。有人可以通过显示我需要运行的命令序列来帮助我,以便能够像往常一样推送代码吗?
penguin@linux$ git push origin master
To git@github.com:<name>/<project>.git
! [rejected] master -> master (non-fast-forward) error: failed to push some refs to 'git@github.com:<name>/<project>.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
答案 0 :(得分:1)
让我们解决这个相当长的评论(我应该在另一条评论中做到这一点,但这根本不适合所以,所以我回答了另一个问题,即,&#34;如何分离和重新连接HEAD工作&#34;):
Tnx torek我设法通过您提供的链接强制删除该错误。我也有一些独立的HEAD问题,我跟随Razan Paul在这里发帖Fix a Git detached head?但是在修复之后,我在分离的HEAD模式下的所有更改都丢失了。我有副本,所以我可以手动重新创建它我猜。因此,将来当我想回到本地工作目录上的最新工作版本时。什么程序最适合我的情况?我看到了很多不同的建议,我不知道对我来说什么是最好的
(顺便说一句,在向某人发表评论时,您可能希望使用@<name>
语法,以便他们收到警报。
你需要的是一本合适的Git书。在我看来,最好的免费版本是Pro Git 2 book。 (没有很多,如果有的话,其他免费的那些&#34;最好的&#34;在这里可能真空。:-))一个较短的非书参考,我发现有用的是Think Like (a) Git,因为Git是在一些非常简单的图论理论之上构建的 - 但除非你知道这一点,直到你意识到这一点,你才会陷入this xkcd cartoon。
(我甚至有my own start on a book,但这些天我没有时间研究它。)
您可以在Git中使用许多工作流程。但要记住的第一件事就是Git&#34;存储单元&#34;因为它是它拼命想要保护的东西,所以你可以把它取回 - 是提交。这就是你在推送时遇到问题的原因:你告诉其他一些Git:扔掉一些提交。 Git不想这样做。
提交由其哈希ID唯一标识。这些哈希ID对人类来说并不是非常有用,所以Git为我们提供了分支名称之类的东西来记住特定的ID - 但在某些情况下,您可能不得不求助于原始ID,例如,您可以使用鼠标剪切和粘贴。 / p>
Git希望保持提交意味着当你使用分离的HEAD进行提交时,Git也试图保留它们。默认情况下,它会这样做至少30天。您可以使用git reflog
找到哈希ID。如果您使用git reset --hard
制作Git&#34;忘记&#34;在分支上的提交(而不是分离的HEAD),Git在分支名称上保留那些 ID至少30天引用日志。每个分支名称都有一个reflog,HEAD
本身就有一个。
最后,一个附加 HEAD-attached与detached相反 - 就像你git status
所说的那样,&#34; on&#34;某个特定的分支:
$ git status
On branch master
...
在这种情况下,分支名称master
是Git实际识别您现在已检出的提交的方式;并且名称HEAD
只是附加到名称master
。
为了使这一切正常, Git向后工作 。
要真正理解所有这些意味着什么,您需要绘制提交图。请记住,每个提交都有自己唯一的哈希ID - 那些十六进制数字的丑陋的40个字符长的字符串,如5be1f00a9a701532232f57958efab4be8c959a29
- 但是那种非常好的,所以你可能只想使用单个小图纸的字母:
A <-B <-C <--master
这是一个非常新的存储库,只有三个提交。我们先制作A
,然后制作B
,然后制作C
。 (当我们进入第27次提交时,我们将用完提交的名称,因此您可以看到为什么Git使用更长的哈希ID。)
由于Git向后工作,名称master
标识,而不是提交A
,而是提交C
。我们说名称master
指向 C
。
提交C
,作为我们的第三个提交,其中包含名称 - 我们的第二个提交的哈希ID,提交B
。我们说C
父提交是B
。因此,将C
指向 B
。同样,B
在其中包含提交A
的哈希ID,因此B
指向A
。
提交A
是第一次提交。它无法指回先前的提交,所以它不会。这使得提交A
变得特别:它是 root commit 。每个非空的存储库至少有一个,第一个提交。
当您运行git log
时,Git将从您的当前提交提交C
开始,在此处向后工作:它会显示C
,并且然后,由于C
指向B
,Git也会显示B
。由于B
指向A
,Git也会显示A
;但是A
是根提交,所以Git可以停止。
由于我们已经master
了,所以让我们进行新的提交D
。我们会使用源git add
文件执行任何操作,并运行git commit
以创建D
。
D
指向何处?好吧,显然它必须回到C
。所以Git让D
拥有C
的父提交:
A <-B <-C <-D
Git的最后一步是更改名称master
,使其保存提交D
的哈希ID,为我们提供以下图片:
A <-B <-C <-D <--master
请注意,所有箭头必须指向向后。此外,所有内提交的箭头都会被冻结:D
指向C
,而不是其他任何地方。 更改的唯一箭头是来自分支名称的箭头!因此,我倾向于在没有内部箭头的情况下绘制它们,以节省空间并使其更好地适应:
A--B--C--D <-- master
这是理解Git的另一个关键:随着时间的推移分支名称的移动。分支获取新的提交,名称指向分支上的 last 提交 - 什么Git调用提示提交。 Git使用此提示提交来查找该分支的下一个较旧的提交:提示的父级。 Git使用 提交来查找其以前的提交,依此类推,一直回到root提交。
HEAD
通常只标识分支名称通过添加来自C
的分支,让上述存储库复杂化:
A--B--C--D <-- master
\
E <-- develop
在这里,我们现在有两个分支。名称develop
标识提交E
,其父级为C
。如果我们现在运行:
git checkout master
我们将on branch master
,git status
会说;如果我们现在创建一个新的提交F
,它的父级将是D
。如果我们改为git checkout develop
并创建新的提交F
,则其父级将为E
。所以Git需要知道:我们在哪个分支?这是我们需要以名称HEAD
绘制的地方:
A--B--C--D <-- master (HEAD)
\
E <-- develop
或:
A--B--C--D <-- master
\
E <-- develop (HEAD)
当您HEAD
这样附加时,它会附加到分支名称。当您进行新的提交时,Git将更改分支名称,以便它指向您刚刚进行的新提交。
如果您发现自己处于detached HEAD
模式,通常是因为您直接检出了较旧的提交。例如,让我们检查提交B
,同时保留我们拥有的所有内容:
A--B <-- HEAD
\
C--D <-- master
\
E <-- develop
我不得不弯曲图形线以适应HEAD
,但现在HEAD
指向直接以提交B
。
如果我们现在制作一个新提交F
,其父级将为B
,而Git将HEAD
直接指向 到F
:
A--B--F <-- HEAD
\
C--D <-- master
\
E <-- develop
请注意,每当Git创建 new 提交时,HEAD
直接(如果已分离)或间接(如果附加到分支名称)的提交也会更改!刚刚提交的父级总是 HEAD
,而现在HEAD
是新的提交,这是再次当前提交。
(这也是父母不知道孩子的哈希ID的原因,但孩子确实知道自己父母的身份.Git 向后工作,因为孩子们知道他们的父母:父母在孩子被创造时存在;但是父母提交 - 这些是只读的并且及时冻结 - 不知道他们将来会获得什么样的孩子。)
但是,一旦我们重新附加HEAD
,我们就会失去&#34;提交F的ID:
A--B--F <-- ???
\
C--D <-- master (HEAD)
\
E <-- develop
谁记得F
的身份证?答案是:只有reflogs 。
如果你想继续提交F
,你应该在你的reflogs中找到它的ID并附上一个名字 - 分支或标签名称,通常是:
A--B--F <-- newbranch
\
C--D <-- master (HEAD)
\
E <-- develop
现在newbranch
会记住F
的ID。如果你做了两个提交,F
和G
,当你有一个超级的HEAD时,你必须找到以后的 / em>以某种方式确定您的名字指向G
,以便您拥有:
G <-- newbranch
/
A--B--F
\
C--D <-- master (HEAD)
\
E <-- develop
而不是:
G <-- ???
/
A--B--F <-- newbranch
\
C--D <-- master (HEAD)
\
E <-- develop
这就是为什么在分离的HEAD上进行大量提交并不是一个好主意:从哈希ID中可以很难说,哪些提交是 tip-most 。
答案 1 :(得分:0)
git明确提到当前的分支,其中您的工作未使用远程存储库进行更新,因为其他人已将其代码提交到该存储库。
首先,您需要获取远程存储库,然后提交代码
注意:此处 origin 是您的远程存储库位置 可能已添加
例如:考虑到你在主分支上工作
git pull origin master /* To update with the remote repository */
git push origin master /* To push your updated code */