前言
Git作为一个当前被最广泛使用的版本控制开发工具,是每一个学习软件开发的程序员所必须熟悉的。这里我将所有的Git指令收编整理,列出一个简单的表项,方便自己以后查询。对于初学者,可以从这个教程入手,可以非常快的理解其内在的功能。
指令整理
git init
: 初始化当前目录为一个新的仓库,该仓库下包含一个master主分支
git init --bare
: 初始化当前目录为一个新的仓库,该仓库下不包含任何内容,一般用于初始化git服务器
git clone REMOTE_URL LOCAL_REPOSITORY_NAME
: 将位于REMOTE_URL上的仓库拉取到本地并且重命名为LOCAL_REPOSITORY_NAME
git status
: 查看当前git仓库的状态
git add filename1 [filename2|filename3]
: 将文件添加至index缓存目录中,可以一次性添加多个文件
git commit -m 'comment'
: 将缓存目录下变动的内容提交至仓库中,comment中填写备注
git commit -a -m 'COMMENT'
:快速提交,不经过缓存
git commit --amend
: 将暂存区中的文件和上一次提交合并
git diff [-filename]
: 查看当前工作区状态和上一次提交区别,若指令中包含文件名,则是查看当前文件和上一次提交的文件的区别
git diff --staged
: 查看已暂存的将要添加到下次提交里的内容
git log
: 查看变更日志
git log [-p] [-NUM] [-stat]
: -p用来显示每次提交的内容差异, -NUM用来说明显示最近NUM次的代码提交, -stat用来说明每次提交的简略的统计信息
git log --graph --pretty=oneline[full|fuller|short]
: 用图形化精简的展示变更日志
git reflog
:查看每一次操作,可以用来查找误删或者误移的版本
git checkout -- file
: 可以丢弃工作区的修改,本质上checkout 文件指令是将工作区的文件回退至上次提交时的状态,上次提交可以是git commit 或git add操作,所以一旦误删,也可以通过该指令从缓存中回退该文件。
git reset HEAD filename
: 将仓库中的内容覆盖给索引去,其实这个指令等价于git reset --mixed HEAD filename,也就是将版本库中的这个文件覆盖缓存中的该文件
git reset [--hard|mixed|soft] [HEAD~n|commid id]
: 将HEAD指针回退至之前某个提交版本,在这里hard指强制回退,会同时刷新仓库,缓存和工作区文件,可能会带来数据的丢失。soft只会刷新仓库的文件,而缓存和工作区文件不会发生变动,如果想要提交还可以重新提交。mixed会刷新仓库和缓存区的内容,但不会修改工作区的内容。
git rm filename
: 删除文件,之后用git commit指令提交删除
git rm --cached FILE_NAME
:从缓存区而不是从工作区删除文件,通常用于误提交
git remote add origin git@server-name:path/repo-name.git
: 添加远程仓库URL
git push [-u] remoter-branch-name local-branch-name
: 向远程仓库提交代码,在第一次提交时需要加上-u指令
git clone git@server-name:path/repo-name.git
: 将远程的库拷贝至当前的目录下
git checkout -b branchname
: 创建分支并切换进入分支
git branch branchname
: 创建分支
git checkout branchname
: 进入分支
git branch
: 查看当前所有的分支,其中当前所在的分支名前会有*号标记
git branch -r
: 查看远程分支
git merge [--no-ff] [-m comment] branchname
: 将名为branchname的分支合并到当前的分支上,默认情况下采用fast-forward的形式合并分支,可以使用--no-ff取消该模式,保证日志可以记录每一次合并,从而不丢失分支信息。-m可以为合并添加备注
git merge --abort
: 放弃当前的合并
git branch -d branchname
: 将名为branchname的分支删除
git branch -D branchname
: 将名为branchname的分支强制删除,因为若分支中的信息没有提交会无法删除,此时可以使用强制删除
git stash[@{n}]
: 将工作现场以及缓存区中的内容“储藏”起来,等以后恢复现场后继续工作。可以多次stash,可以通过指定n说明使用第n次存储的内容
git stash --keep-index
: 不要储藏任何你通过 git add 命令已暂存的东西
git stash [--include-untracked|-u]
: 默认情况下,git stash 只会储藏已经在索引中的文件。 如果指定 --include-untracked 或 -u 标记,Git 也会储藏任何创建的未跟踪文件。
git stash --patch
: Git 不会储藏所有修改过的任何东西,但是会交互式地提示哪些改动想要储藏、哪些改动需要保存在工作目录中
git stash branch
:
git stash list
: 查看存储的工作现场
git stash apply [stashId]
: 恢复现场但是不清除stash的内容,默认为最近一次stash内容
git stash drop
: 删除stash内容
git stash pop
: 恢复现场的同事清除stash内容
git remote [-v]
: 查看远程仓库的信息
git remote add
: 添加一个新的地址为url的仓库并且取名为shortname
git remote show [remote-name]
:查看远程仓库的状态
git remote rename
:远程仓库的重命名
git remote rm
: 删除远程仓库在本地的引用
git checkout -b localbranchname origin/remotebranch
: 默认情况下,clone下来后只能看到远程master分支,若想在远程的其它分支上工作,就必须创建和远程分支对应的分支
git pull [remote] [branch]
: 把最新的提交从远程分支抓下来,并且直接和当前的分支进行合并
git fetch [remote-url|remote-branch-name]
:将远程仓库的数据拉取到本地仓库,但是不会合并或修改当前的工作
git branch --set-upstream localbranchname origin/remotebranchname
: 创建本地分支和远程分支的链接关系
git branch -v
: 查看每一个分支的最后一次提交
git branch [--merged|--no-merged]
: 过滤列表中已经合并和尚未合并到当前分支的分支
git push origin branch-name
: 向远程分支提交更新
git tag -a tagname [-m comment] [commitid]
: 将当前的分支打上标签,默认是最近一次提交,也可以指定某次提交打上标签
git tag
: 查看所有标签
git show tagname
: 查看标签的详细信息
git tag -d tagname
: 删除某个标签
git push origin tagname
: 将标签推送到远程服务器
git push origin --tags
: 一次性推送所有还未推送的标签
git tag -d tagname + git push origin :refs/tags/tagname
: 删除远程的标签
git config --global alias.
:将COMPLETE_NAME的指令换成等价的缩写SHORT_NAME指令
git clean
: 从工作目录中移除未被追踪的文件, 最好先运行git stash --all
git grep -n [--count]
: 从提交历史或者工作目录中查找一个字符串或者正则表达式, -n是指Git所找到的匹配行号, --count使 Git 输出概述的信息,仅仅包括哪些文件包含匹配以及每个文件包含了多少个匹配, -p看匹配的行是属于哪一个方法或者函数, --and 标志来查看复杂的字符串组合
场景举例
初次安装GIT后对git进行配置
git的配置文件位于三个目录下,它们分别对应着不同的作用域,可以通过git config进行操作
:
1./etc/gitconfig
: 包含系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system 选项的 git config 时,它会从此文件读写配置变量
2.~/.gitconfig 或 ~/.config/git/config
: 只针对当前用户。可以传递 --global 选项让 Git 读写此文件
3..git/config
: 当前仓库中的config文件,其配置针对当前仓库。
这三个文件下一个级别覆盖上一个级别的内容。也就是说本地的覆盖用户的,用户的覆盖全局的。
在第一次安装完毕后, 应当适当的配置git的信息
git config --global user.name "NAME"
git config --global user.email "EMAIL"
git config --list
列出所有Git当时能找到的全部配置
git config KEY
查找键为KEY的配置文件信息,比如git config user.name
这些global
属性会作用于当前系统该用户所有的操作。如果想要对特定的仓库采用不同的属性,应当在那个仓库目录下使用没有--global
标签的命令
利用github新建一个远程仓库
在最开始的时候需要新建一个git项目并在远程github上同步从而实现项目的共同开发。基本流程就是先在远程仓库上新建一个项目,然后将本地的项目和远程连接。
2.初始化仓库,记住不要在仓库中添加任何内容包括readme文件
3.创建完成后获得仓库的URL,可以一键复制
至此远程的仓库就创建完成了。然后我们需要在本地新建一个项目来初始化这个远程仓库。假设我现在在本地有一个项目,项目的名称为TestGit
1.cd DIR_OF_TESTGIT/TestGit
:进入项目目录
2.git init
: 新建一个仓库,这时的仓库为空。这时如果用git branch
指令会看到当前目录下不存在任何分支
3.git remote add origin YOUR_URL
: 将刚才复制的仓库的URL添加到本地并命名为origin
4.git add *
:将当前项目中的所有文件添加到缓存中
5.git commit -m 'init'
:将项目提交到本地仓库并且备注为init。在第一次提交之后git会自动初始化一个master分支。这是用git branch
指令查看会看到master分支
6.git push --set-upstream origin master
:将master分支提交到远程origin上,这里--set-upstream实际上就是声明当前项目的远程url
至此你的本地项目和远程项目就实现了初始化的同步
Fork操作
往往存在这么一种情况,当我在github上看到一个优秀的开源项目,我想将它‘拷贝’到自己的github下,并且在该项目上进行自己的更新,这种操作叫做Fork
。网上有许多很优秀的文章讲解了如何进行Fork操作,这里我整理一下指令:
1.git remote -v
: 查看当前的远程仓库中是否记录了原作者的仓库,如果没有则进入1.1步进行添加
1.1git remote add upstream origin-author-git-address
: 将原作者的git地址添加到本地远程仓库中,该仓库名为upstream,当然也可以取名为别的
2git fetch upstream
: 将作者仓库中的代码获取至本地仓库
3git checkout branchname
: 切换到想要合并的分支上去
4git merge upstream/master
: 将远程仓库的master分支和当前的分支合并,也可以远程的其他分支
5git add filename + git commit -m 'comment'
: 将本地的修改提交至本地的仓库
6git push
: 将本地仓库提交到自己的远程仓库
7 如果希望原作者可以查看自己的修改,可以向原作者发出pull request请求,原作者会试情况将你的更新合并到他自己的代码库中
本地更改代码后分支提交和合并操作
在很多情况下,一旦出现代码需要更改的情况,我们往往会在master分支上独立开一个分支来进行开发,防止因为更改造成master上代码的崩溃。创建分支编写后再合并到master的操作如下:
1git branch branchname
: 新建分支
2git checkout branchname
: 切换到新建的分支中去。至此可以进行相应的独立开发,且不会影响master
3git add filename
: 将文件添加到缓存中
4git commit -m COMMENT
: 将缓存中的文件添加到仓库中
5git push
: 将仓库中更新的代码添加到远程仓库上,然后在gitlab上提出merge请求
如果这时候master上代码发生变化,那么你当前所在的分支的master代码就和当前master版本不同,需要你先更新当前分支的master部分的代码,然后再将合并完成以后的代码提交到远程仓库。这里要记住,一定要先保存本地在workspace的修改。不然一旦合并,本地的内容就被抹去了。此时的操作如下:
1git fetch origin master
: 将master代码更新到当前分支的仓库中
2git merge origin master
: 将master代码和本地的分支合并,并且修改冲突的部分
3git push
: 如果有冲突,则还是需要通过add和commit操作提交到本地长裤,然后本地仓库中的代码push到远程仓库。
在和远程仓库达成一致后,再向master发送merge请求
配置gitignore
当我们想要对代码进行配置管理的时候,我们有时候并不希望一些文件被上传。例如,在IDEA编辑器中开发项目时,往往项目中会有IDEA自己的配置文件,一般存放在.idea文件夹中。当项目上传时,我们可能并不希望将这些文件也上传,因此我们需要配置.gitignore
文件来声明不需要提交的文件。
cat .gitignore
进入根目录下并且创建.gitignore文件
在其中里面添加希望屏蔽的文件,文件名称可以按照glob 模式匹配
文件 .gitignore 的格式规范如下:
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
glob 模式是指 shell 所使用的简化了的正则表达式。
星号(*)匹配零个或多个任意字符;
[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);
问号(?)只匹配一个任意字符;
如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。
使用两个星号(*) 表示匹配任意中间目录,比如a/**/z
可以匹配 a/z, a/b/z 或 a/b/c/z
等。
在这里可以参考我的正则表达式的文章
RESET VS CHECKOUT
GIT回退是一门大学问,在没有彻底理解GIT的工作区域和工作流程之前,很难透彻的明白如何对GIT仓库进行回退。然而回退在使用GIT的过程中是一个很重要的功能。所以我们必须静下心来,理解这个流程。
这个教程对回退讲解的非常透彻,建议笔者先看两遍这篇文章,理解后再使用下文中整理的具体指令。
git reset --soft
: 将HEAD指向的分支移动指向COMMIT_ID的提交
git reset --soft HEAD~
: 将HEAD指向的分支指向HEAD的父提交,本质上是撤销了上一次的COMMIT
git reset --mixed
: 在指向COMMIT_ID提交的基础上更新INDEX区(缓存区)的内容
git reset --hard
: 在mixed的基础上更新了工作区(workspace)的内容。这个操作很危险,因为它会直接覆盖工作区的内容。
git reset [--mixed|--hard|--soft]
: 如果在reset指令中填写了文件名或者路径名,reset会跳过移动HEAD指向的指针的步骤,直接将FILE_NAME或DIR_NAME更新为COMMIT_ID提交中的样子,至于更新的区域则由mixed或是hard或是soft决定。COMMIT_ID在不填写的情况下默认为HEAD。
git checkout [COMMIT_ID]
: 与运行git reset --hard [branch]
很相似,它会更新所有三棵树使其看起来像 [COMMIT_ID],不过有两点重要的区别。 首先不同于reset --hard
,checkout
对工作目录是安全的,它会通过检查来确保不会将已更改的文件弄丢。 其实它还更聪明一些。它会在工作目录中先试着简单合并一下,这样所有还未修改过的文件都会被更新。 而reset --hard
则会不做检查就全面地替换所有东西。 第二个重要的区别是如何更新 HEAD。 reset 会移动 HEAD 分支的指向,而 checkout 只会移动 HEAD 自身来指向另一个分支。所以checkout指令可以用来切换分支
git checkout [COMMIT_ID] [filename]
: 类似于git reset --hard [branch] file
,该操作不安全
其它的场景等后续使用的时候继续更新!
学习资料
Git Pro