Git 中的一些其他常用命令

1、查看提交的历史版本(git log)

我们可以使用 git log 命令来查看提交的历史版本。

默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面。每个版本都有一个 SHA-1 校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。

1.1、展开显示每次提交的内容差异(git log -p)

git log -p 命令将会列出每次提交时相对于上一版本的修改。用 -2 则只显示最近的两次更新

1.2、只显示每次提交的差异的简要信息(git log --stat)

只列出了添加的文件,修改过的文件数,以及添加和移除的行数 

 1.3、将每个提交放在一行显示(git log --pretty=oneline)

 --pretty 选项可以指定使用完全不同于默认格式的方式展示提交历史。比如用 oneline 将每个提交放在一行显示,这在提交数很大时非常有用。

2、撤销操作

2.1、修改最近的一次提交(git commit --amend)

有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了,想要撤消刚才的提交并对提交重新进行修改,可以使用  --amend 选项重新提交。(被覆盖掉的版本其实也可以通过reflog查看,然后恢复该版本)

-- amend 命令的提交操作将会以现在的工作区中的文件为准。现在的工作区中有多少文件,或者工作区对文件进行了修改并加入了暂存区,那么使用 --amend 命令提交的版本将会以现在的工作区为准,并会覆盖掉刚才的提交。--amend 命令将会启动编辑器以重新输入说明。

2.2、取消已暂存的文件(git reset HEAD filename)

假如有两个修改过的文件,我们想要分开提交,但不小心用 git add . 全加到了暂存区域。我们可以使用 git reset HEAD filename 命令来将某一文件从暂存区中取出来,这时该文件将会又回到了之前已修改未暂存的状态。

2.3、取消对文件的修改(git checkout filename)

如果觉得刚才对某一文件的修改完全没有必要,可以使用git checkout filename 命令来让文件回到没修改之前的状态(也就是恢复到了最新一版本的文件状态)

(该命令只对暂未缓存的文件有效,如果已经放到了暂存区将没有效果。如果先放到了暂存区然后再进行修改,这时将会用暂存区的文件重写该文件)

这条命令有些危险,因为所有对文件的修改将会不见并且也恢复不了,所以在用这条命令前,请务必确定真的不再需要保留刚才的修改。

请记住,任何已经提交到 Git 的都可以被恢复。所以,可能失去的数据仅限于没有提交过的,因为那些对 Git 来说它们就像从未存在过一样。

3、回退版本(git reset --hard 目标版本号)

使用 git reset --hard 目标版本号能回退到指定的版本,或者使用 git reset --hard HEAD^ 命令能回退到上一版本。

在Git中,用 HEAD 表示现在所处的版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,往上100个版本写100个^可以写成HEAD~100。(在当前所处版本回退版本时,即使回退到 HEAD 版本,当前的修改也不会保存。若想先保存当前修改,可以使用 -stash 命令)

先使用 git log (或者git log --pretty=oneline)命令查看历史版本,在 commit 字段后的就是版本号。使用 git reset --hard commitID 就能回退到指定版本,此时本地的HEAD指向回退到的版本。注意此时通过 git log 命令并不能看到当前版本(已经回退)的之前那些版本的信息,如果我们回退了某一版本然后又想退回去,可以通过 git reflog 命令查看所有 HEAD 指向过的版本信息。

3.1、查看 HEAD 所指向过的所有版本(git reflog)

git reflog 命令能查看所有 HEAD 指向过的版本信息,包括你在某一时刻回退后当时指向的版本。通过前面的版本号可以看到有哪些时刻指向的是同一版本。

git reflog 可以很好地帮助你恢复你误操作的数据,例如你错误地回退了一个旧的版本,这个时候你可以使用reflog去查看在误操作之前的信息,并且使用git reset --hard 去恢复之前的状态。 

4、储藏修改的内容(git stash)

4.1、储藏修改(git stash、git stash save '说明')

当你正在修改项目中的文件代码,而这时你可能会因为某种原因要回退到之前的某一版本或者是你想转到其他分支上进行一些其他的工作,但是你不想把现在的修改提交,也不希望在Git上看到当前修改的版本,而且你还想把当前的修改保留着,当你在其他地方的工作完成后还能将修改应用回来,此时你可以用 git stash命令。git stash save '储藏说明'  命令能为每个储藏提供说明信息。

“‘储藏”“可以获取你修改的内容,包括你修改过的所有已被追踪的文件和暂存的变更,并将它保存到一个堆栈中,随时可以重新应用。运行 git stash 命令过后你的工作目录就会变干净了,这时你的文件代码也会回退到没修改之前,而你的修改全部都保存在了一个堆栈中。

4.2、git stash -u 暂存新建文件

请注意,git stash 默认情况下不会暂存新建的文件,而我们平常也需要将新建的文件进行暂存的,此时要加上 -u 参数

git stash -u
git stash save -u '保存信息说明'

默认情况下, git stash 命令会把以下修改存储到一个新的堆栈中。堆栈中的内容(stash)可以被所有分支访问。

git stash 命令暂存的文件包括:暂存区中的修改、工作区中已经存在的文件的修改

也就是说,默认情况下,git stash 命令不会存储以下文件:工作区中新增的文件(untracked files)、被版本库忽略的文件(.gitignore 中定义的)

如果你还想要存储 untracked files,可以使用 -u 选项

参考:https://blog.csdn.net/lamp_yang_3533/article/details/80370380

4.3、查看储藏列表(git stash list)

要查看现有的储藏,你可以使用git stash list 命令。

4.4、重新应用储藏(git stash apply)

git stash apply stash@{1}:git stash apply 命令应用储藏默认是应用最上面的储藏(也是你最新导出的),通过指定名字可以应用更早导出的储藏,示例:git stash apply stash@{1}

git stash pop:apply 选项只应用储藏,该储藏仍然留在栈上,要想在应用的同时移除该储藏,可以通过 git stash pop 命令,这个命令只支持应用第一个储藏。

git stash apply --index:重新应用储藏时,之前放在暂存区的修改并不会自动也放在暂存区,而是处于未暂存状态。如果你想应用的同时之前放在暂存区的现在也一样,这时可以使用 git stash apply --index 命令。 

你可以在跟导出储藏的同一分支且干净的工作目录上应用储藏;但是一个干净的工作目录和应用到相同的分支上并不是应用储藏的必要条件。你可以在其中一个分支上保留一份储藏,随后切换到另外一个分支,再重新应用这些变更。在工作目录里包含已修改和未提交的文件时,你也可以应用储藏——Git 会显示有冲突如果有任何储藏无法干净地被应用。

4.5、移除指定储藏(git stash drop 储藏名)

想要移除指定储藏,可以运行git stash drop 加上储藏名,这时并不会应用该储藏

5、Git 中本地与远程不同步时

当你在本地修改了代码,而如果远程别人也进行了版本提交,此时你直接使用 git pull 会覆盖掉你本地修改的代码。

而要想避免这种情况,有两种办法:

5.1、先本地提交一个版本再拉取

将本地提交为一个版本,最后再 git pull 拉取,Git 会自动合并对应的远程分支代码

git add .
git commit -m '修改了代码'
git pull  

使用 git pull 后(相当于先使用了 git fetch,然后再使用了git merge),Git 会自动生成一个提交版本,此时可能会弹出一个输入窗,需要你输入此时合并的说明信息,也就是此时提交版本的说明信息。

如果合并有冲突,Git 不会生成提交版本,而是等你手动解决冲突,解决完冲突后应该手动提交一个版本。

这样做的缺点是必须先在本地提交一个版本,然后合并后还得生成一个版本才行。要避免这种情况,可以参考下面的方法,即只要合并后生成一个版本即可

5.2、使用 git stash (推荐)

可以使用 git stash 命令将本地修改全部放入暂存(注意:默认不包括新生成的文件),然后拉取代码,再使用 git pop 应用修改

git stash    //或者是 git stash -u
git pull
git stash pop

参考:https://blog.csdn.net/yangfengjueqi/article/details/82848962

6、git 上的HEAD、Index、Working Copy的概念

1)HEAD:可以理解为当前本地分支的最近的一次提交,即本地的版本信息中的最新 commit 版本

2)Index(索引):在本地修改之后已经执行过了 git add 操作的文件,即暂存区中的文件

3)Working Copy(工作目录):工作副本指的是你已经进行了修改,但是没有执行任何 git 操作的文件,即已经修改过但是还没放到暂存区的文件。

7、git 上的回退操作的三个参数(git reset --soft、--mixed、--hard)

在 git 上你可以使用 git reset 命令来进行回退操作,该命令有三种模式:软模式、混合模式和硬模式。三种模式对于本地修改的保留越来越少。

7.1、软模式(git reset --soft commitId)

该模式的回退操作只是将你的本地提交版本回退到你指定的 commit id 版本上,但是在这个 commit id 版本之后的所有修改,包括后面版本的修改和你的本地的已提交和未提交的修改都不会被删除,此时你只需要重新提交一个版本即可,在这个 commit id 版本之后的所有修改都会保存在新生成的版本中。

git reset --soft xxxx  // xxxx 表示你要回退到的版本的commit id

git status   //查看状态你可以看到你的所有修改都没有丢失

//然后重新提交一个版本即可
git add .
git commit -m '新版本'

这个模式的回退操作的影响只是让你的本地仓库丢失了一些提交版本的注释信息而已。也就是说软模式的回退只是改变了你的当前版本指向HEAD而已,你的索引Index和工作目录working copy都不会发生任何改变。

在执行了软模式回退之后,如果那些丢失的版本信息之前已经提交到了远程仓库的时候,你在执行了回退操作之后是不能将本地仓库直接推送给远程仓库的,Git 会提示你的本地版本落后于远程版本,必须得先拉取再推送。所以说,已经推送到了远程仓库中的版本信息是不会丢失的,你不可能在本地回退以后就能直接推送至远程上。除非你进行强制推送,但这个命令非常危险,因为这会导致你的远程仓库中也会丢失这些版本信息,而且很可能会找不回来,所以不要轻易尝试。

7.2、混合模式(git reset --mixed commitId,不带参数时的默认模式)

混合模式是 git reset 命令不指定任何参数时默认执行的模式,该模式的回退操作会改变你的当前版本指向HEAD和索引 Index,而工作目录working copy是不会发生改变的。也就是说的将你的当前版本指向改成你指定的版本,同时你执行了 git add 命令的文件将不会被继续放在暂存区,因为该回退操作并不会保留暂存区的状态,但是你在本地的所有修改都不会被删除掉。

该回退操作命令除了把你的暂存状态清掉,并不会对你的本地修改有任何影响,所以该回退操作影响也不算很大。

7.3、硬模式(git reset --hard commitId)

硬模式的回退操作非常危险,因为该模式的回退会直接将你的本地文件代码回退至你所指定的版本,并且不会保留你在该版本之后的所有修改。不过所幸的是也可以通过 git reflog 命令查看本地曾指向过的所有版本号然后再回滚至之前所指向的最新版本,由此可以撤销该操作。

硬模式的回退操作将会重置HEAD、Index和working copy,直接将你的本地文件回复至指定的版本的内容,也不会保留你本地未提交的修改,所以建议在执行该命令之前,先将本地修改提交为一个版本,以便能再次回滚至当前工作的版本。

硬模式命令的使用和撤销参考上文中的:3、回退版本(git reset --hard 目标版本号) --> https://www.cnblogs.com/wenxuehai/p/10401380.html#_label2

8、强制推送本地仓库至远程仓库(git push -f origin master,非常危险)

在 git 中,为了保护远程仓库安全和避免用户误操作,在很多情况下你是无法将本地仓库直接推送至远程仓库中的,比如说你的本地版本落后于远程仓库版本等等,这时候就会提示你先拉取再推送或者进行其他命令。

比如说我们再执行了回退操作 reset 后,是不会允许你直接将本地版本推送至远程仓库中的,因为此时你的本地版本就落后于远程仓库的版本,这也是为了避免用户乱操作,导致远程仓库的版本被胡乱修改。此时如果你确确实实是为了回退至某指定版本,因为你在这个指定版本之后的修改操作都出错了,不需要保留的话,Git 中也是可以强制将本地仓库推送至远程仓库的。

比如:在远程仓库中最新的版本是 merge branch ....,如下图所示:

然后我们在本地执行了回滚版本的操作,将本地版本回滚到了 "提交3",:

 如果我们直接推送会提示我们必须先拉取再推送,这也是为了避免我们的远程仓库被误操作导致版本回退。

 但如果我们确确实实是要回滚版本,并且需要推送至远程仓库中给所有协同者使用的话,我们可以使用强制推送命令:

git push -f origin 分支名
//比如:
git push -f origin master

此时在远程仓库中就可以看到在 “提交3” 版本之后的版本信息都不见了

这个命令非常危险,因为这会使得你的远程仓库中丢失了一些版本的提交信息,除非这个操作是非常必要的,否则不要轻易尝试强制推送命令。

当然你也可以通过 git reflog 命令来查看你所有曾指向过的版本信息,然后再通过 git reset --hard 命令来指向之前的最新版本来避免强制推送导致的错误。但是 git reflog 命令只是针对于你本地曾指向过的版本信息,在远程仓库中的项目的并不会记录这些信息,也就是说除了你以外,任何新克隆项目的人和未拉取最新版本的人都不曾感知过之前的最新版本的存在,也就无法操作回退至之前的最新版本。或许会出现除了你以外其他人都无法回退至最新版本的情况,所以说不要轻易尝试这个命令。

原文地址:https://www.cnblogs.com/wenxuehai/p/10401380.html