Git使用教程常用命令总结

Git基本操作

Git是世界上最流行的版本控制工具,熟练使用git工具可以帮助我们高效的工作,也是程序员的必备技能之一。

当我们在工作路径下执行git init 命令便初始化一个本地仓库,它会在当前路径下创建一个隐藏的.git目录,该目录包括了文件的版本信息,git对文件的管理控制是增量的,使用哈希算法对文件内容进行版本控制,请不要随便删除.git目录,因为这将导致你的工作空间是完全脱离版本控制,造成不可追溯的后果。

Git为了对我们工作空间内容进行合理安全的版本控制,划分为三个区,工作区(也就是我们的本地开发的文件内容),暂存区(使用git add命令添加文件到暂存区),仓库区(使用git commit提交到仓库)。一个文件想要被完整的纳入版本控制中,还得按顺序走完这个三区,最终到达仓库区。

为了处理工作流的问题,git还有创建分支的功能,面对不同人群进行独立开发互不影响,大家可以自己在所需的分支上进行开发任务,如果任务完成还可以进行合并操作,如果合并失误,提交错误,git还可以 使用revert或者reset等命令进行撤销回退操作。这些操作构成了一套git工作流。

1. git init

创建git仓库,既可以在当前目录有文件的时候使用,也可以是空白文件的时候使用,初始化完毕会在当前路径下创建.git文件夹(该文件夹已隐藏),该文件夹包含了git相关的元数据,切记不要删除该目录,除非你很明确的知道你不需要git版本控制了。

2. git clone

克隆一个远程仓库到当前路径,将该仓库整个拉取复制下来,该命令也顺便创建了本地git仓库,并且自动创建了一个名为 origin 的远程连接,指向原有远程仓库

3. git add

为了对文件进行合理控制,git将文件区域划分为三个区域:工作区(Working Directory),暂存区(英文叫Staged, 或index),提交区(Commit)。该命令主要的作用是将工作目录中的文件添加到 Git 的缓存区,缓存区允许可以多次添加文件,也可以使用 git add . 注意后面是个点,表示将当前路径下的所有文件全部添加到缓存区。你也可以使用 git status 命令查看缓冲区有那些文件。为了防止部分无用的文件被提交到缓存区,你还应该在当前路径下建立一个忽略文件.gitignore,该文件包括了一些表达式,告诉git不应该把那些文件添加到缓冲区,对于我们项目生成的编译文件和日志文件一般直接忽略掉。缓存区最大的作用是给你提供一个安全过度的机制,让你可以对文件是否纳入版本控制中提供撤销和确认的一个区域。很多人以为第一次提交了就不用再使用add操作了,其实在之后文件的更改,也可以使用 add 命令对某部分文件进行添加到缓存区,可能你修改了很多文件,而只想commit其中几个文件,该命令非常实用。

4. git commit

主要是将暂存区里的改动提交到本地的版本库。每次使用该命令我们都会在本地版本库生成一个40位的哈希值,这个哈希值也叫commit-id,commit-id在版本回退的时候是非常有用的,它相当于一个快照,可以在未来的任何时候通过与git reset的组合命令回到这里。为了使我们在以后追查代码节点更加容易,我们通常会对当前提交进行一个补充说明,使用 git commit -m “message” -m 参数后紧跟文字说明。

git commit --amend

命令是修复最新提交的便捷方式。它允许你将缓存的修改和之前的提交合并到一起,而不是提交一个全新的快照。它还可以用来简单地编辑上一次提交的信息而不改变快照。amend 不只是修改了最新的提交——它进行了一次替换。对于 Git 来说,这看上去像一个全新的提交。常见的用途,你已经commit过一次,发现又要修改一个文件,而你不想作为一个新的版本记录,那么就可以使用这个命令共享上次的版本记录。

5. git status

命令显示工作目录和缓存区的状态。你可以看到哪些更改被缓存了,哪些还没有,以及哪些还未被 Git 追踪(Untracked files)。status 的输出不会告诉你任何已提交到项目历史的信息。如果你想看的话,应该使用 git log 命令。

使用 git status 命令 你可能会看到如下几个部分:

Changes to be committed: 已经被添加到缓存区,但是还没有被commit的文件,也就是等待提交的文件

Changes not staged for commit: 已经commit过的文件,但是内容已改变,还没有被添加到缓存区的文件

Untracked files: 该文件还没有被纳入版本控制中,也就是没有被追踪的文件

6. git log

命令显示已提交的快照。你可以列出项目历史,筛选,以及搜索特定更改。git status 允许你查看工作目录和缓存区,而 git log 只作用于提交的项目历史。log 输出可以有很多种自定义的方式,从简单地筛选提交,到用完全自定义的格式显示。

git log -n <limit> 显示多少条提交记录,默认是时间倒序

git log -p 显示每个提交全部的差异(diff),这也是项目历史中最详细的视图。

git log <file> 显示包含特定文件的提交

git log --oneline 查看最简略的内容,一行信息

git reflog 可以查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作),是用来恢复本地错误操作很重要的一个命令。reflog并不是repo(仓库)的一部分,它单独存储,而且不包含在pushes,fetches或者clones里面,它纯属是本地的。 reflog可以很好地帮助你恢复你误操作的数据,例如你错误地reset了一个旧的提交,或者rebase,……,这个时候你可以使用reflog去查看在误操作之前的信息,并且使用git reset --hard <commitID>去恢复之前的状态

7. git checkout

这个命令有三个不同的作用:检出文件、检出提交和检出分支。检出提交会使工作目录和这个提交完全匹配。你可以用它来查看项目之前的状态,而不改变当前的状态。检出文件使你能够查看某个特定文件的旧版本,而工作目录中剩下的文件不变。

git log --oneline 查看历史记录

git checkout a1e8fb5 选择一个记录的版本id,检出该版本,注意,在执行此命令之前,你本地工作区有文件被修改,并且该文件还未被添加到缓存区并且该文件之前有commit过,则该文件必须先add ,再commit之后才能执行检出操作;如果工作区有文件未被添加到缓存区,之前也未被commit过,也就是该文件没有被纳入到版本控制中,那么无论检出与否,该文件会一直保留,此时也可以执行检出操作。总而言之,在执行检出之前,确保你的所有被纳入到版本控制中的文件都要提交,没有纳入的可以不管,因为切换版本也会保留的。

需要提醒你的是,如果你在切换版本后,也就是切换到历史版本中,想对历史版本文件进行修改,请一定要建立一个新的分支,再提交保存;如果你只是在历史版本中,对文件进行修改,也commit过,在切换分支会丢失本次提交的。

git checkout master 切换到主分支master

git checkout -b branchName 如果分支不存在,创建分支并且切换到新创建的分支下,如果已经存在请使用上面的命令切换

8. git revert

命令用来撤销一个已经提交的快照版本,最后加上一个撤销了更改的新提交,而不是从项目历史中移除这个提交。版本会递增,不影响之前提交的内容。

git revert HEAD 撤销前一次 commit
git revert HEAD^ 撤销前前一次 commit
git revert commit <commitID> 撤销指定的版本,撤销也会作为一次提交进行保存。

9. git reset

如果说 git revert 是一个撤销更改安全的方式,你可以将 git reset 看做一个 危险 的方式。当你用

git reset 来重设更改时(提交不再被任何引用或引用日志所引用),我们无法获得原来的样子——这个撤销是永远的。使用这个工具的时候务必要小心,因为这是少数几个可能会造成工作丢失的命令之一。

git reset 有很多种用法。它可以被用来移除提交快照,尽管它通常被用来撤销缓存区和工作目录的修改。不管是哪种情况,它应该只被用于 本地 修改——你永远不应该重设和其他开发者共享的快照。

git reset --mixed HEAD^

--mixed是默认的,也可以不写,回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件(未提交的也 不受影响)

git reset --soft HEAD^

回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区,不影响原来本地的文件(未提交的也不受影响)

git reset --hard HEAD^

回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被恢复的版本替换,如果当前的文件不在回退的版本中会被删除的(未提交的不受影响) ,慎重!!!

温馨提醒:

HEAD指针指向的是最新的提交节点。而HEAD^代表的是前一次的提交节点。而HEAD~2代表的是前两次的提交节点

撤销(revert)和重设(reset)对比

  1. git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
  2. git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进

10. git rebase

变基是将分支移到一个新的基提交的过程。从内容的角度来看,rebase 只不过是将分支从一个提交移到了另一个。主要目的是为了保持一个线性的项目历史。比如说,当你在 feature 分支工作时 master 分支取得了一些进展。现在要将你的 feature 分支整合进 master 分支,你有两个选择:直接 merge,或者rebase 。前者会产生一个三路合并(3-way merge)和一个合并提交,而后者产生的是一个快速向前的合并以及完美的线性历史。

rebase黄金定律
永远不要在一个远程或者他人分支上去执行rebase操作(比如在master,develop,release分支上去rebase自己分支),也就是说永远不要在一个已经在中央库中存在的分支上去rebase,只能在你自己使用的私有分支上去rebase。

12. git merge

当不同分支上的文件都发生了更改时,就会遇到把这些更改进行合并,这个时候要用到两个操作:Merge 或者 Rebase 。如果没有冲突,则直接合并。如果有冲突,则需要先解决冲突,再执行。

如果你在feature分支下进行合并maser分支操作,会把上图C4节点和C6节点进行合并,并产生M节点,这个操作也叫三路合并。

git checkout feature 
git merge master

13. git remote

命令允许你创建、查看和删除和其它仓库之间的连接。通常是为了连接中央仓库,多成员协作开发项目使用。如我们通常使用github,当我们使用git clone一个项目的时候,默认创建了一个远程链接为 origin 的远程分支,我们可以在本地开发然后push到远程分支上,也可以fetch远程分支,进行合并操作。

git remote -v 查看远程连接名字和链接信息

git remote add <name> <url> 对本地仓库添加一个远程链接,并将name作为远程链接的别名

git remote rm <name> 删除一个远程连接,这里的name即是创建时候的别名

git remote rename <old-name> <new-name> 将远程连接从 <old-name> 重命名为 <new-name>

14. git pull

取回远程主机某个分支的更新,再与本地的指定分支合并。

一句话总结git pullgit fetch的区别:git pull = git fetch + git merge

git fetch不会进行合并执行后需要手动执行git merge合并分支,而git pull拉取远程分之后直接与本地分支进行合并。更准确地说,git pull使用给定的参数运行git fetch,并调用git merge将检索到的分支头合并到当前分支中。

git pull origin master 将远程origin主机的master分支拉取过来和本地的当前分支进行合并。

上面的pull操作用fetch表示为:

git fetch origin master:brantest
git merge brantest

相比起来git fetch更安全一些,因为在merge前,我们可以查看更新情况,然后再决定是否合并。

15. git push

命令是你将本地仓库中的提交转移到远程仓库中时要做的事。它和 git fetch 正好相反,fetch 将提交导入到本地分支,而 push 将提交导出到远程分支。它可以覆盖已有的更改,所以你需要小心使用。

git push origin master

16. git branch

分支代表了一条独立的开发流水线。由于实际开发中,有同事负责修复bug问题,有同事在加新功能,而新问题需要紧急去线上主分支上合并发布到线上,而新功能则不急于合并到线上主分支。为此我们可以建立三个分支:线上分支master,开发分支dev,新功能分支feature,在以后需要发布线上的时候,可以直接合并到线上主分支,这样子可以大家保持独立的开发,互不影响。分支在实际开发中大量运用。

git branch 列出仓库所有分支

git branch feature 创建分支feature,如果需要切换到该分支,执行 git checkout feature

git branch -d feature 删除指定分支。这是一个安全的操作,Git 会阻止你删除包含未合并更改的分支

git branch -m dev 将当前分支命名为 dev


关注技术,分享知识,共同进步,互相帮助

 Redis入门知识归纳总结(上部分-大概介绍)
Java多线程开发中如何优雅的停止线程 
上一篇:Redis入门知识归纳总结(上部分-大概介绍)
下一篇:Java多线程开发中如何优雅的停止线程
评论

如果我的文章对你有帮助,或许可以打赏一下呀!

支付宝
微信
QQ