Git和GitHub入门(3/3)
之前的文章在這裡。
Git和GitHub入门(1/3)
Git和GitHub入门(2/3)
在这种情况下应该怎么办?
因为经常有在工作中出现的场景,所以让我们一起练习一下吧。
取消对暂存区的添加
如果不小心把文件加到了暂存区,但接下来的提交中又不想包含它,这种情况。
试试把文件「test2」添加到暂存区。
$ git add test2
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: test2
答案已经显示出来了。
(使用“git reset HEAD …”来取消暂存)
按照导航提示,将test2从分布环境还原。
$ git reset HEAD test2
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
test2
nothing added to commit but untracked files present (use "git add" to track)
在将其添加到暂存区之前,你已经回到了原来的状态。
在这里,出现了一个新词。 “HEAD” 是指什么呢?
头是什么
HEAD是指当前工作分支的最新提交。
我们可以用git log命令来查看提交日志。
$ git log
commit 7022b44cb174e7d1d932a950d052fcdec9b36408 (HEAD -> master, origin/master)
Author: hoge <53826023+hoge@users.noreply.github.com>
Date: Sat Oct 12 22:15:23 2019 +0900
Create README.md
commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date: Sat Oct 12 19:13:31 2019 +0900
first commit
现在,HEAD指向最新添加README时的提交。通过git show HEAD可以查看最新提交的内容。
$ git show HEAD
commit 7022b44cb174e7d1d932a950d052fcdec9b36408 (HEAD -> master, origin/master)
Author: hoge <53826023+hoge@users.noreply.github.com>
Date: Sat Oct 12 22:15:23 2019 +0900
Create README.md
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bab6eaf
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# sample
+sample for remote repository
顺便说一下,最新提交的前一次提交被称为HEAD^。
每增加一个^,表示往前一个提交。
最新提交的前一个提交会成为第一个提交。
$ git show HEAD^
commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date: Sat Oct 12 19:13:31 2019 +0900
first commit
diff --git a/test1 b/test1
new file mode 100644
index 0000000..e69de29
换句话说,git reset HEAD test2将使得HEAD回到初始状态。
在commit后面的f733bfe11003832f28f4803481cbe086e1903e4a是一个提交ID,用它替代HEAD输入同样效果。
修改提交时的评论
如果您想要修改最新提交的注释。
首先,将文件“test2”添加到暂存区,并进行提交。注释将被设为“添加hoge”。
$ git add test2
$ git commit -m "add hoge"
[master c26d97e] add hoge
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test2
使用git log命令来确认已提交的事项。
$ git log
commit c26d97e9a6c9460a0b9790f3040b12beca1750f0 (HEAD -> master)
Author: hoge <hoge@gmail.com>
Date: Sun Oct 13 15:11:59 2019 +0900
add hoge
我将把评论修改为“添加测试2”。
$ git commit --amend -m "add test2"
让我们确保已经对提交日志的注释进行了修正。
$ git log
commit 255795fc007dc6c5e64cc4acd2a54ca1e62f64c4 (HEAD -> master)
Author: hoge <hoge@gmail.com>
Date: Sun Oct 13 15:11:59 2019 +0900
add test2
评论已经被修正了。
撤销提交
我不小心提交了错误的内容,但是当有一些修改遗漏时,想要取消提交的情况下使用。
这个也可以使用git reset。
$ git reset --soft HEAD^
在Git中,HEAD指的是最新提交的前一个提交,因此倒回到最新提交的前一个提交意味着回到最新提交的前一个状态。如果加上–soft选项,那么只会撤消提交操作,并回到被暂存的状态。
让我们来查看提交记录吧。
刚才的“add test2”的提交已经消失了,对吧。
$ git log
commit 7022b44cb174e7d1d932a950d052fcdec9b36408 (HEAD -> master, origin/master)
Author: hoge <53826023+hoge@users.noreply.github.com>
Date: Sat Oct 12 22:15:23 2019 +0900
Create README.md
commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date: Sat Oct 12 19:13:31 2019 +0900
first commit
让我们通过git status查看暂存的状态。看起来test2文件已经被添加了。
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: test2
值得一提的是,如果没有使用–soft选项,添加到暂存区的操作将一并取消。
另外,如果使用–hard选项,工作中的文件状态也将变为HEAD^的状态(最新提交的前一个状态)。也就是说,test2文件将被删除。(请小心。。)
恢复被推送的文件
当不小心点击了Push按钮的时候,可以取消这个Push。
如果多人在进行使用同一个远程代码库进行工作的话,这种操作有些危险。我们需要确保大家知道如何正确取消Push。
假裝什麼都沒發生
首先,将文件“test2”提交并推送到远程仓库中。
$ git commit -m "add test2"
[master 72225df] add test2
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test2
$ git push origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 264 bytes | 264.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To https://github.com/hoge/sample.git
7022b44..72225df master -> master

看起来也添加了提交日志呢。
$ git log
commit 72225dfff26c3e09114614739f584b5b6c9701af (HEAD -> master, origin/master)
Author: hoge <hoge@gmail.com>
Date: Sun Oct 13 16:54:55 2019 +0900
add test2
commit 7022b44cb174e7d1d932a950d052fcdec9b36408
Author: hoge <53826023+hoge@users.noreply.github.com>
Date: Sat Oct 12 22:15:23 2019 +0900
Create README.md
commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date: Sat Oct 12 19:13:31 2019 +0900
first commit
首先,按照之前所述的方法取消提交。
$ git reset --soft HEAD^
$ git log
commit 7022b44cb174e7d1d932a950d052fcdec9b36408 (HEAD -> master)
Author: hoge <53826023+hoge@users.noreply.github.com>
Date: Sat Oct 12 22:15:23 2019 +0900
Create README.md
commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date: Sat Oct 12 19:13:31 2019 +0900
first commit
测试2的提交消失了,是吗?
在这种情况下,重新提交(push)。
$ git push origin mastser
error: src refspec mastser does not match any.
error: failed to push some refs to 'https://github.com/hoge/sample.git'
哎呀,出错了。
是因为远程仓库中记录的提交日志与推送的提交日志不一致。
具体来说,远程仓库中仍然存在着“add test2”的日志,但是新推送的提交日志中却不再包含“add test2”。
虽然不太礼貌,但我们会使用 -f 进行强制推送。
$ git push -f origin master
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/hoge/sample.git
+ 72225df...7022b44 master -> master (forced update)
没有出现错误,可以进行推送了。

解决冲突
如果远程仓库和本地仓库在同一个地方有更新的情况下,当从本地仓库推送到远程仓库时会出现错误,无法推送。这种情况被称为冲突。如果有多人同时更新同一个远程仓库,也有可能发生这种情况。

接下来,在本地仓库中也要修改README的内容。
使用vi命令,删除README中的所有内容,并输入”test”。
然后,将其添加到暂存区,并尝试一次性执行提交和推送操作。
$ vi README.md
$ git add README.md
$ git commit -m "mod README"
$ git push origin master
To https://github.com/maru-e/sample.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://github.com/hoge/sample.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first 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.
当您提交时出现了错误。
是由于远程仓库的更改与本地仓库的更改冲突,因此不知道应该优先采用哪一个。
当遇到这种情况时,你会想知道远程仓库发生了什么样的更改,对吗?
在这种情况下,你可以使用git fetch将远程仓库的更改内容获取到本地仓库中。
$ git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/hoge/sample
7022b44..7beb0cd master -> origin/master
您可以使用以下命令来检查本地仓库的主分支(master)最新的提交(HEAD)与远程仓库(origin)的主分支之间的差异。
$ git diff HEAD origin/master
diff --git a/README.md b/README.md
index 9daeafb..a099415 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-test
+modify comment
可以看到README.md文件已被修改,本地代码库中文件内容为”test”,远程代码库中文件内容为”modify comment”。
如果可以覆盖远程仓库的内容,请使用git push -f origin master来强制推送本地仓库的内容至远程仓库。
如果您想要覆盖本地存储库中的远程存储库内容,可以使用git pull origin master进行覆盖。
通过检查差异,选择其中一种方法来修正内容。