本文整理了一些git的常用操作和配置。
基本操作
仓库管理
clone到本地仓库
git clone git_addr ["指定目录"]
远程拉取更新本地仓库
git pull
添加文件
git add file or folder
删除文件(也可以直接删除,git commit -am
会识别)
git rm [-rf] file or folder
提交部分变更的文件
git commit file1 file2 ... -m "message"
提交所有本地更新的文件
git commit -am "message"
查看本地仓库状态
git status
本地仓库更新同步到远程master
git push origin master
查看本地仓库变更
git diff [filename]
查看stage的文件的变更
git diff --cached
查看提交记录(最近一次-1)
git log
git log -p filename
git log -p -1 filename
git log --pretty=oneline filename
搜索提交记录
git log --oneline | grep "xxx"
查看仓库的远程url
git remote -v
把已有的仓库及提交记录推送到新仓库(git支持本地代码对应多个远端)
git remote add new_origin git@xxx.com:group_name/name.git
git push -u new_origin master
// 查看分支与远端的对应关系
git branch -vv
显示某次提交的内容
git show <commit_id>
显示某次提交的变更文件列表
git show --pretty="format:" --name-only <commit_id>
查看某次提交某个文件的修改
git show <commit_id> filename
显示command的help
git help <command>
导出工程
git archive master | gzip > latest.tgz
获取其他分支上的某个commit
git cherry-pick <commit_id>
分支操作
创建或切换分支
git checkout -b <分支名>
新创建的分支本地push到远端
git push -u origin <分支名>
列出所有分支
git branch -a
忽略本地修改
本地有修改,未commit时,git pull,这时git pull会提示要先commit或stash,如果不想用本地的,可以先git checkout -f
忽略,再 git pull
清除未track的文件
// 删除未track的文件,但是ignore指定的除外
git clean -f
// 删除当前目录未track的文件,但是ignore指定的除外
git clean -df
// 删除所有未track的文件,包括ignore指定的
git clean -xf
忽略对未commit文件的修改,还原到最近的版本
git checkout -- <file>
回滚到某一次提交纪录
git checkout -f <commit_id>
恢复主干到最新代码
git checkout -f master
合并分支
git merge --no-ff develop
删除错误提交的commit,回退到某个版本
git reset --hard <commit_id>
删除最近一次未push的commit(hard为本地文件也回滚)
git reset --hard HEAD~1
git reset --soft HEAD~1
修改最后一次提交,比如有些时候遗漏了要提交的文件,可以git add下,最后还是一个commit
git commit --amend
选择某一个分支中的一个或几个commit(s)来进行合并
git cherry-pick <commit_id>
回滚操作revert
回滚一个commit
git revert <commit_id>
回滚一次代码merge合并的commit
假设g是一个merge的commit_id:
$ git revert g
error: Commit g is a merge but no -m option was given.
fatal: revert failed
Git 需要你通过 m 或 mainline 参数来指定「主线」。merge commit 的 parents 一定是在两个不同的线索上,因此可以通过 parent 来表示「主线」。m 参数的值可以是 1 或者 2,对应着 parent 在 merge commit 信息中的顺序。
假设分支结构:
a -> b -> c -> f -- g -> h -> G (master)
\ /
d -> e (dev)
$ git show g
commit g
Merge: f e
则:git revert -m 1 g
将会保留 master 分支上的修改,撤销 dev 分支上的修改
储藏操作 stash
储藏当前的工作(tracked - 已跟踪的文件修改 和 staged - 暂存的内容)到栈中,这样当前环境会恢复成分支最新状态
git stash
查看现有的储藏
git stash list
应用储藏
git stash apply [stash@{2}]
清理一份储藏
git stash drop stash@{0}
应用最新一份储藏,并删除
git stash pop
打标签 tag
列出tags
git tag
创建标签
git tag -a v1.4 -m "my version 1.4"
git tag -a v1.2 9fceb02
共享标签(推送到远端)
git push origin --tags
检出标签,这种检出标签只是版本校验码的一个alias
git checkout [tag]
创建分支来检出标签,因为在 Git 中你并不能真的检出一个标签,并不能像分支一样来回移动,也不能直接修改代码提交
git checkout -b version_tag [tag]
打补丁patch
一般使用sourcetree,可以方便的可视化创建补丁文件
查看补丁状态
git apply --stat patch.diff
测试补丁文件是否可以正常应用
git apply --check patch.diff
应用补丁
git am --signoff < patch.diff
变基 rebase
有些时候,比如从开发分支develop拉出mywork分支,做了一些本地commit之后,直接merge回develop可能会产生冲突,或者develop分支的负责人,不清楚你的功能,也无法处理产生的冲突,这时mywork开发者,可以基于develop分支可以rebase一下,处理完后,就好像mywork是从最新的develop节点拉出分支来提交的。
rebase 基本操作,可能需要处理冲突,解决好git-add,再git rebase –continue
git checkout mywork
git rebase develop
git add *
git rebase --continue
终止rebase操作,回到rebase开始前的状态
git rebase --abort
当前分支rebase到最新,减少不必要的默认merge
git pull --rebase
或
git fetch & git rebase
子模块submodule
初始化
使用git clone下来的工程中带有submodule时,初始的时候,submodule的内容并不会自动下载下来的,此时需执行如下命令:
git submodule update --init --recursive
更新
git submodule update
其他操作
生成SSH密钥过程
- 查看是否已经有了ssh密钥:
cd ~/.ssh
- 再生成密钥:
ssh-keygen -t ed25519 -C "your_email@gmail.com"
,按3个回车,密码为空 - 会生成两个文件:id_ed25519和id_ed25519.pub。id_ed25519是私钥,git会自动使用;而id_ed25519.pub是公钥,其内容需要设置到git站点,如github设置ssh密钥
常用git分支管理策略
主分支Master
代码库应该有一个、且仅有一个主分支。所有提供给用户使用的正式版本,都在这个主分支上发布。
开发分支Develop
主分支只用来分布重大版本,日常开发应该在另一条分支上完成。我们把开发用的分支,叫做Develop。
Git创建Develop分支的命令:
git checkout -b develop master
将Develop分支发布到Master分支的命令:
# 切换到Master分支
git checkout master
# 对Develop分支进行合并,并特意产生一条merge记录
git merge --no-ff develop
使用Beyond Compare代码比较
Beyond Compare先在菜单安装好命令行工具
git difftool -t bc3
配置git的alias
git有单独的配置文档~/.gitconfig
,里面可以配置命令来简化操作。
[alias]
st = status
ci = commit
cm = commit -m
br = branch
co = checkout
df = diff --patience
ll = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative
pom = push origin master
up = pull --rebase
merge = merge --no-ff
find = log --oneline | grep
参考资料
- https://git-scm.com/book/en/v2
- http://www.ruanyifeng.com/blog/2012/07/git.html
- http://gitbook.liuhui998.com/index.html
- http://www.cnblogs.com/cspku/articles/Git_cmds.html
- http://www.ihref.com/read-16369.html
- http://hungyuhei.github.io/2012/08/07/better-git-commit-graph-using-pull—rebase-and-merge—no-ff.html
- https://github.com/Microsoft/vscode/issues/5770