一、概述
说Git是现在最火的版本控制工具一点都不为过,但是git有那么多命令,所以这里列出常用的,遇到其他的再google吧。
二、基本概念
- Working Directory(工作区):本地工作的目录
- Staging Area(暂存区):本地和仓库之间的“缓冲”区域
- Repository(本地仓库):本地仓库
- Remote(远程仓库):远程的git仓库(比如github上的仓库)
其他重要的概念:
- Snapshot(快照):git会为每个文件每次提交生成快照,所以其可以很快恢复
- Checksum(校验和):git存储的时候会使用sha-1 hash生成校验和,也就可用用来指定每次commit(提交)
- Branch(分支):分支只是一个指向commit的指针,所以很轻量级
- HEAD:指向当前分支的一个指针
- reflog:每一次当前HEAD被更新(切换分支,pull新变化,重写提交历史,提交新变化)都会在reflog中新建记录。
三、新建本地仓库
git init
#在当前目录新建一个Git仓库
git init <directory>
#新建一个目录,并初始化为一个空的Git仓库
git init --bare <directory>
#初始化一个Git仓库,但是忽略工作区,用于共享仓库。新建的仓库以.git结尾
git clone <repo>
#在当前目录克隆远程仓库(可通过HTTP、SSH、GIT协议),并在本地仓库和远程仓库直接建立连接
git clone <repo> <directory>
#在<directory>克隆远程仓库
git clone -o <remote-name> [-b <branch>] <remote-url>
# 克隆远程仓库,使用<remote-name>(而不是默认的origin)
四、配置
配置文件地址(项目配置覆盖用户全局配置,覆盖系统范围配置):
<repo>/.git/config
– 项目配置~/.gitconfig
– 用户git配置,--global
配置的地方$(prefix)/etc/gitconfig
– 系统全局配置
git config --list
# 显示当前git配置
git config [--global] user.name <name>
git config [--global] user.email <email>
# 设置提交时的用户名和邮件地址
git config --global alias.<alias-name> <git-command>
# 为git命令设置别名
git config --system core.editor <editor>
# 设置git编辑时使用的编辑器
git config --global --edit
# 使用文本编辑器手动编辑配置文件
五、保存或删除修改
git add [file1] [file2] …
#添加指定文件到暂存区
git add <directory>
#添加指定目录(包括所有子目录和文件)到暂存区
git add .
#添加当前目录所有文件到暂存区
git add -p
#开始一个交互式的会话,每个文件都会要求确认
git commit
# 打开编辑器输入提交信息,保存然后提交
git commit -m "<message>"
# 提交暂存区到本地仓库
git commit [file1] [file2] ... -m "<message>"
# 提交暂存区指定文件到本地仓库
git commit -a
# 提交所有工作区已add过的文件(不是新的文件),自动添加到暂存区,然后提交到本地仓库
提交消息(message)的格式:第一行使用少于50个字的总结,然后留一空白行,然后列出具体改动信息(改动原因、主要变动、以后需要注意的问题)。最后,提供对应网址。(以下例子来自Atlassian Git Tutorial)
Change the message displayed by hello.py
- Update the sayHello() function to output the user's name
- Change the sayGoodbye() function to a friendlier message
git diff
# 比较工作区和暂存区的不同
git diff --staged
# 比较暂存区和最后一次commit的不同
git difftool
# 使用不同的diff工具比较
git rm [file]
# 在仓库、工作区移除文件
git rm --cached [file|directory]
# 在暂存区移除,但在工作区中保留(取消跟踪)
git mv <file_from> <file_to>
# 重命名某文件
查看信息
git status
# 查看工作区和暂存区的状态
Ignoring Files
# 让git add时排除某些文件,可修改.gitignore文件
git log
# 查看整个仓库的历史提交记录(使用默认格式)
git log -n <limit>
# 查看最近<limit>次的提交
git log --oneline
# 在一行中显示每一次的提交
git log --stat
# 显示仓库提交历史,和每次提交变更的文件
git log -p [file]
# 显示指定文件的每次diff
git log --author="<pattern>"
# 使用字符串或正则表达式搜索指定用户的提交
git log --grep="<pattern>"
# 字符串或正则表达式搜索提交信息
git log <since>..<until>
# 显示从<since>到<until>的提交
git log --graph
# 使用ASCLL图形显示历史记录
git log <file>
# 显示某个文件的提交历史
提交的ID(校验和)、HEAD、分支名称都可用于指代某次提交。~字符可用于指代先前的提交,比如HEAD~1指代当前提交的上一次提交。
gitk
# 打开图形化的git历史界面
六、撤销更改
git checkout <commit>
# 恢复<commit>版本到工作区,可使用git checkout master回到当前状态。如果在这个状态 # 下提交,则会新建一个匿名分支,可根据情况合并
git checkout -- <file>
# 撤销工作区某个文件的修改,恢复暂存区到工作区
git checkout .
# 撤销所有文件的修改
git checkout <commit> <file>
# 恢复<commit>版的<file>到工作区和暂存区,可通过提交让<file>成为<commit>时的状态
git reset <file>
# 只撤销对<file>的暂存,不会更改工作区
git reset | git reset HEAD
# 撤销所有的暂存,保持暂存区和最近的一次提交一致
git reset --hard
# 撤销所有的暂存和工作区的更改,恢复至最近一次提交的状态
git reset <commit>
# 移动当前分支的HEAD指向<commit>,重置暂存区到<commit>版本,从<commit>版本开始的提交都会恢复至工作区
git reset --hard <commit>
# 移动当前分支HEAD指向<commit>,重置暂存区和工作区被跟踪的文件到<commit>版本
git revert <commit>
# 新建一次提交,来撤销<commit>所做的提交,
# 除<commit>外的所有提交都会被新建的commit提交
git stash
git stash pop
# 暂时将未提交的变化移除,稍后再移入
git clean -n
# “排练”git clean操作,显示哪些文件将被移除
git clean -f
# 移除当前目录未被跟踪的文件,不会移除被.gitignore忽略的文件
git clean -f <path>
# 移除指定路径下的未被跟踪的文件
git clean -df
# 移除当前目录未被跟踪的文件和目录
git clean -xf
# 移除当前目录未被跟踪的文件,包括.gitignore忽略的文件
七、改写提交历史
git commit --amend
# 使用一次新的提交替代上一次提交
# 如果文件没有任何修改,可用来修改上一次commit的提交信息
git commit --amend <file1> <file2> …
# 重做上一次提交,并包含<file1><file2>的新变化
git rebase <base>
# 重新指定当前分支的基准
git rebase -i <base>
# 使用交互式的rebase重置基准为<base>
git reflog
# 显示reflog历史
git rebase -i
可以使用的命令:
• pick:正常选中
• reword:选中,并且修改提交信息;
• edit:选中,rebase时会暂停,允许你修改这个commit
• squash:选中,会将当前commit与上一个commit合并
• fixup:与squash相同,但不会保存当前commit的提交信息
• exec:执行其他shell命令
八、分支
图来自《Pro Git》
git branch
# 列出仓库所有本地分支
git branch -v
# 列出所有远程分支
git branch -vv
# 列出所有本地分支,并显示关联的远程分支信息
git branch -a
# 列出所有远程和本地分支
git branch --merged
# 列出所有已和当前分支合并的分支
git branch --no-merged
# 列出所有未与当前分支合并的分支
git branch <branch>
# 新建<branch>分支,但是不切换到新分支
git checkout -b <new-branch>
# 新建并切换到<new-branch>分支
git branch <new-branch> <start-point>
# 新建本地分支,基于特定起始位置(<start-point>可为commit、tag或者branch-name,如何省略,则默认为当前HEAD)
git checkout --track <remote>/<branch>
git checkout -b <new-branch> <remote>/<branch>
# 新建本地分支,基于远程仓库的指定分支
git checkout <new-branch>
# 新建本地分支,与同名的远程分支建立跟踪关系(前提:1、<new-branch>分支不存在;2、存在和<new-branch>同名的远程分支)
git branch (-u | --set-upstream-to) <remote-branch>
# 建立跟踪关系,在本地分支和远程分支之间
git checkout <existing-branch>
# 切换分支,并更新暂存区和工作区
git merge <branch-name>
# 把<branch-name>分支和当前分支合并
git merge --no-ff <branch>
# 把当前分支与<branch>分支合并,但是无论如何都会生成合并信息(包括快速合并)
git branch -d <branch>
# 删除分支(如果分支未与当前分支合并,则会删除失败)
git branch -D <branch>
# 强制删除某分支
九、远程同步
git remote
# 显示当前所对应远程仓库的简称
git remote -v
# 显示远程仓库的名称和URLs
git remote add <shortname> <url>
# 添加地址为<url>的远程仓库<shortname>
git remote show <remote-name>
# 显示远程仓库的信息,以及和本地仓库的联系
git remote rename <source-name> <target-name>
# 重命名远程仓库<source-name>为<target-name>
git remote rm <remote-name>
# 删除远程仓库<remote-name>
git fetch <remote-name>
# 抓取所有远程仓库的分支及其commit(但不与本地分支合并),可使用git merge与本地分支合并
git push <remote> <branch>
# 推送本地分支到远程分支,不建立联系
git push -u origin <branch>
# 推送本地分支到远程分支,并建立联系
git pull [remote]
# 抓取远程仓库与当前分支对应的分支,并与当前分支合并(merge)
git pull --rebash <remote>
# 抓取远程仓库与当前分支对应的分支,并与当前分支进行rebase
十、标签
git tag
# 列出所有tag
git tag -l <pattern>
# 列出符合<pattern>的tag
git tag -a <tag-name> [-m <tag-message>]
# 在当前commit下新建annotated tag
git tag <tag-name>
# 新建lightweight tag
git tag [-a] <tag-name> <commit>
# 在指定<commit>创建tag
git show <tag-name>
# 查看tag
git push <remote> <tag-name>
# 提交指定tag
git push <remote> --tags
# 提交所有tag
git checkout -b <branch-name> <tag-name>
# 新建指向指定tag的分支