本文主要介绍 Git常见操作。
几个专用名称的译名如下:
1 2 3 4
| Workspace: 工作区 Index / Stage: 暂存区 Repository: 仓库区(或本地仓库) Remote: 远程仓库
|
新建代码库
在当前目录新建一个Git代码库
新建一个目录,并将其初始化为Git代码库
下载一个项目和它的整个代码历史
配置
Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。
显示当前的git配置
编辑Git配置文件
1
| git config -e [--global]
|
设置提交的代码时的用户信息
1 2
| git config [--global] user.name "[name]" git config [--global] user.email "[email address]"
|
增加删除文件
添加空文件夹
空目录无法被提交,在空目录中随便放一个空文件即可
1 2
| touch build/.keep git add build/.keep
|
添加指定文件到暂存区
添加指定目录到暂存区
添加当前目录的所有文件到暂存区
添加时忽略.gitignore文件规则
添加每个变化前,都会要求确认
对于同一个文件的多处变化,可以实现多次提交
将文件添加到暂存区后,使用git status命令查看。
若文件出现在Changes to be committed这行下面,说明文件已经被放到暂存区。
若文件出现在Changes not staged for commit这行下面,说明已跟踪文件内容发生了变化,但还没有放到暂存区。
删除工作区文件,并将这次删除放入暂存区
从暂存区撤销这次删除的文件,工作区文件不改变
1
| git restore --staged [file]
|
恢复工作区删除的文件
停止追踪指定文件,但该文件会保留在工作区
改名文件,并将这个改名放入暂存区
1
| git mv [file-original] [file-renamed]
|
代码提交
提交暂存区到仓库区
提交暂存区的指定文件到仓库区
1
| git commit [file1] [file2] ... -m [message]
|
提交工作区自上次commit之后的变化,直接到仓库区
提交时显示所有diff信息
使用一次新的commit,替代上一次提交
如果代码没有任何新变化,则用来改写上一次commit的提交信息
注意:如果需要push到远程仓库,需要添加
--force 选项。
1
| git commit --amend -m [message]
|
重做上一次commit,并包括指定文件的新变化
1
| git commit --amend [file1] [file2]
|
提交一个空的commit
1
| git commit --allow-empty -m [message]
|
分支
列出所有本地分支
列出所有远程分支
列出所有本地分支和远程分支
新建一个分支,但依然停留在当前分支
新建一个分支,并切换到这个分支
1
| git checkout -b [branch]
|
新建一个分支,指向指定commit
1
| git checkout -b [branch] [commit]
|
新建一个分支,与指定的远程分支建立追踪关系,此时仍在原来分支
1
| git branch --track [branch] [remote-branch]
|
切换到指定分支,并更新工作区
切换到上一个分支
建立追踪关系,在现有分支与指定分支之间
1
| git branch --set-upstream [branch] [remote-branch]
|
合并指定分支到当前分支
选择一个commit,合并进当前分支
1
| git cherry-pick [commit]
|
删除分支
1
| git branch -d [branch-name]
|
删除远程分支
1 2
| git push origin --delete [branch-name] git branch -dr [remote/branch]
|
标签
列出所有tag
新建一个tag在当前commit
新建一个tag在指定commit
删除本地tag
删除远程tag
1
| git push origin :refs/tags/[tagName]
|
查看tag信息
提交指定tag
提交所有tag
1
| git push [remote] --tags
|
新建一个分支,指向某个tag
1
| git checkout -b [branch] [tag]
|
查看信息
显示有变更的文件
以简洁的方式查看更改
新添加的未跟踪文件有??标记,新添加到暂存区中的文件有A标记,修改过的文件前面有M标记。修改过,暂存后又做了修改的文件前面有MM标记。
显示当前分支的版本历史
查看日志点线图
1
| git log --oneline --graph
|
查找某个人的commit
1
| git log --oneline --author=[username]
|
显示commit历史,以及每次commit发生变更的文件
查找commit信息中是否含有某些关键字
1
| git log --oneline --grep=[keyword]
|
查找某一时间段的commit
1
| git log --oneline --since="1pm" --until="4pm" --after="2021-05"
|
搜索提交历史,根据关键词
显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
1
| git log [tag] HEAD --grap feature
|
显示某个文件的版本历史,包括文件改名
1 2
| git log --follow [file] git whatchanged [file]
|
显示指定文件夹的每一次diff
显示过去五次提交
1
| git log -5 --pretty --oneline
|
显示所有提交过的用户,按提交次数排序
显示指定文件是什么人在什么时间修改过
显示暂存区和工作区的差异
此命令比较的是工作目录(workspace)中当前文件和暂存区域(staged)快照之间的差异。也就是修改之后还没有暂存起来的变化内容。
git diff本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动,所以有时候一下子暂存了所有更新过的文件,运行git diff后却什么也没有,就是这个原因。
显示暂存区和上一个commit的差异
1 2
| git diff --cached [file]
|
显示工作区与当前分支最新commit之间的差异
显示两次提交之间的差异
1
| git diff [first-branch]...[second-branch]
|
显示今天你写了多少行代码
1
| git diff --shortstat "@{0 day ago}"
|
显示某次提交的元数据和内容变化
显示某次提交发生变化的文件
1
| git show --name-only [commit]
|
显示某次提交时,某个文件的内容
1
| git show [commit]:[filename]
|
显示当前分支的最近的几次提交
远程同步
下载远程仓库的所有变动
显示所有远程仓库
显示某个远程仓库的信息
1
| git remote show [remote]
|
增加一个新的远程仓库,并命名
1
| git remote add [shortname] [url]
|
取回远程仓库的变化,并于本地分支合并
1
| git pull [remote] [branch]
|
上传本地指定分支到远程仓库
1
| git push [remote] [branch]
|
强行推送当前分支到远程仓库,即使有冲突
1
| git push [remote] --force
|
推送所有分支到远程仓库
撤销
恢复暂存区的指定文件到工作区
恢复某个commit的指定文件到暂存区和工作区
1
| git checkout [commit] [file]
|
恢复暂存区的所有文件到工作区
重置暂存区的指定文件,与上一次commit保持一致,但是工作区不变
重置暂存区与工作区,与上一次commit保持一致
重置当前分支的HEAD为指定commit,同时重置暂存区,但工作区保持不变
重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
1
| git reset --hard [commit]
|
重置当前分支的HEAD为指定commit,但工作区和暂存区保持不变
1
| git reset --keep [commit]
|
新建一个commit,用来撤销指定commit
后者的所有变化都被前者抵消,并且应用到当前分支
暂时将为提交的变化移除,稍后再移入
1 2
| git stash git stash pop
|
其他
生成一个可供发布的压缩包
在本地目录下关联远程仓库
1
| git remote add origin git@github.com:git_username/repository_name.git
|
取消本地目录下关联的远程库:
1
| git remote remove origin
|
查看git commit 历史
回退到某个commit版本
1
| git reset --hard <COMMIT_ID>
|
查看本地分支
切换到某个分支
但是,这时候 git 可能会提示你当前处于一个“detached HEAD" 状态。因为
tag 相当于是一个快照,是不能更改它的代码的。
如果要在 tag 代码的基础上做修改,你需要一个分支:
创建并切换到新分支
1
| git checkout -b <新分支> <本地分支>
|
tag和branch的区别
tag就像是一个里程碑一个标志一个点,branch是一个新的征程一条线;
tag就是一个只读的branch,一般为每一个可发布的里程碑版本打一个tag。
tag就是给commit的hash校验和取的一个名字,比较直观,方便记忆和使用,和branch不是一个维度,点与线的区别.
.gitignore 编写
规范:
- 所有空行或者以#开头的行都会被Git忽略。
- 可以应用标准的glob模式匹配,他回递归地应用在整个工作区中。
- 匹配模式可以以/开头放在递归。
- 匹配模式可以以/开头结尾指定目录。
- 要忽略指定模式以外的文件或者目录,可以在模式前面加上
!叹号取反。
glob模式
glob模式是指shell所使用的简化了的正则表达式。
- 星号(*)匹配零个或多个任意字符;
- [abc]匹配任何一个序列在方括号中的字符(要么匹配一个a,要么匹配一个b,要么匹配一个c);
- 问号(?)只匹配一个任意字符;
- 在方括号中使用短划线分割两个字符,表示所有在这两个字符范围内的都可以匹配(比如【0-9】表示匹配所有0到9的数字);
- 使用两个星号(**)表示匹配任意中间目录,比如
a/**/z可以匹配a/z、a/b/z、或a/b/c/z等。
.gitignore例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # 忽略所有的.a文件 *.a
# 但跟踪所有的lib.a, 即使你在前面忽略了.a文件 !lib.a
# 只忽略当前目录的TODO文件,而不忽略subdir/TODO /TODO
# 忽略db目录下所有后缀是 .sqlite3的文件 /db/*.sqlite3
# 忽略任何目录下名下为build的文件夹 build/
# 忽略 doc/notes.txt, 但不忽略 doc/server/arch.txt doc/*.txt
# 忽略 doc/ 目录以及所有子目录下的 .pdf文件 doc/**/*.pdf
|
具体文件的编写可以参考:https://github.com/github/gitignore
一个仓库可以只有根目录下有一个.gitignore文件,它递归地应用到整个仓库。子目录下也可以有额外的.gitignore文件,这只作用于它所在的目录。
新增文件时,只要符合.gitignore的规定,这个文件就会被无视
git clean
git clean
命令用来从工作目录中删除没有被tracked的文件。
git clean 经常和
git reset --hard一起结合使用。reset只影响被跟踪过的文件,所以需要clean来删除没有track过的文件,结合使用这两个命令能让工作目录完全回到一个指定的commit状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| git clean -n
git clean -f
git clean -f [path]
git clean -df
git clean -xf
|
下面的例子要删除所有工作目录下面的修改, 包括新添加的文件.
假设你已经提交了一些快照了, 而且做了一些新的开发
1 2
| git reset --hard git clean -df
|
运行后,工作目录和缓存区回到最近一次commit时候一摸一样的状态,git
status会告诉你这是一个干净的工作目录, 又是一个新的开始了!