Git 的优势
- 离线工作:每个人的电脑都是一个完整的版本库,即使不连接服务器,也可以在本地进行版本管理;
- 强大的分支管理;
创建仓库
clone 一个已存在的仓库
git clone ssh://user@domain.com/repo.git
创建一个新的本地仓库
git init
本地仓库和远程仓库:
本地仓库以一个隐藏的文件夹(
.git
)的形式存储在项目的根目录下;
远程仓库没有工作目录,完全由.git
仓库目录组成。开发团队使用远程仓库进行数据共享和交换。
本地修改
查看工作副本的状态:git status
查看与上次版本文件的不同:git diff
添加所有修改到暂存区,等待下次提交:git add .
提交暂存区的文件到本地仓库:git commit -m "commit comment"
修改上次的提交(请勿修改已经推送到远程的提交记录):git commit --amend
或者,直接带上要修改的注释:git commit --amend -m "This is the correct message"
也可以添加更多的改动到上次的提交中:
git add file.txt
git commit --amend -m "commit message"
查看日志
查看所有的提交记录:git log
指定显示 log 的数目:git log -<num>
查看提交时文件的变化:git log -p
显示指定文件的所有修改:git log -p <file>
谁,在什么时间,修改了文件的什么内容:git blame <file>
只看某人的提交:git log --author=<name>
每条日志单行显示:git log --pretty=oneline
查看每一次操作,包括回退:git reflog
查看分支合并图:git log --graph --pretty=oneline --abbrev-commit
查看远程仓库的日志:git log origin/master
分支操作
创建、合并和删除分支非常快,所以 Git 鼓励使用分支完成某个任务,合并后再删掉分支,这和直接在 master 分支上工作效果是一样的,但过程更安全。
创建新分支(基于当前分支):git branch <new-branch>
创建新的可追溯的分支(基于远程分支):git checkout --track <remote/branch-name>
创建并切换分支:git checkout -b dev
切换分支:git checkout <branch>
查看分支:git branch
查看所有分支(包括远程),并显示最后一次的提交记录:git branch -av
合并分支:git merge <branch>
删除分支:git branch -d <branch>
删除一个没有被合并的分支:git branch -D dev
删除远程仓库的分支:git branch -dr <remote/branch>
下载远程的 dev 分支 :git checkout -b dev origin/dev
设置本地分支 dev 和远程分支 origin/dev 的关联:git branch --set-upstream-to=origin/dev dev
标签操作
Git 标签其实是一个指向某个 commit 的指针,所以创建和删除标签都是瞬间完成的。
给当前的提交打标签:git tag <tag-name>
指定给某次的提交打标签:git tag <tag-name> <commit-id>
用 -a
指定标签名,用 -m
指定说明文字 :git tag -a <tag-name> -m <message> <commit-id>
查看标签:git tag
查看某个标签的信息 :git show <tagname>
推送某个标签:git push origin v1.0
推送所有标签:git push --tags
删除本地标签:git tag -d <tag-name>
删除远程标签:
- 先删除本地标签;
- 然后推送:
git push origin :refs/tags/<tag-name>
远程仓库
添加远程仓库(一般把 remote 命令为 origin
,可以添加多个远程仓库):git remote add <remote> <url>
列出当前配置的远程仓库:git remote -v
查看远程仓库的信息:git remote show <remote>
删除远程仓库:git remote rm <remote>
修改远程仓库的地址:git remote set-url <remote> <url>
更新/下载
下载远程仓库的所有改动到本地,不会自动合并到当前:git fetch <remote>
下载远程仓库的所有改动到本地,自动合并到当前:git pull <remote> <branch>
将本地版本发布到远程仓库:git push <remote> <branch>
第一次推送 master 分支到 origin:git push -u origin master
,添加 -u
,会把本地的 master 分支和远程的 master 分支关联起来,以后推送可以直接使用 git push
比较操作
查看当前工作副本中所有未提交的变化:git diff
指定要查看的文件:git diff <filename>
与版本库的任意版本比较文件:git diff <commitID> -- <file>
比较任意两个版本之间的内容:git diff <commitID> <commitID>
比较两个分支之间的内容:git diff master dev
保存/恢复工作区
不要提交还未完成的工作。
临时需要修改一个bug,当前的任务又没有完成,不能提交。执行 git stash
,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作。
改完 bug 之后,要恢复工作区,继续之前的工作:
查看 stash:git stash list
恢复:git stash apply
,恢复之后,stash 内容没有删除,用 git stash drop
来删除;
恢复并删除:git stash pop
可以执行多次 git stash
保存工作区,恢复的时候,指定 stash id:git stash apply stash@{0}
储藏功能可以帮助我们得到一个干净的工作副本。当然,它还可以应用在很多不同的流程中,强烈推荐在下列情况中储藏你的本地改动:
- 在切换到不同分支之前。
- 在获取(pulling)远程改动之前。
- 在合并(merging)或者衍合(rebasing)一个分支之前。
撤销
在 Git 中,用 HEAD
表示当前版本,上一个版本就是 HEAD^
,上上一个版本就是HEAD^^
,往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
。
放弃工作副本中的所有修改(回退到当前版本):git reset --hard HEAD
回退到指定版本,放弃之后的修改(查看 git log
,已经回退到之前的提交)
git reset --hard <commit-id>
(不使用 --hard
会保留之前的修改,放在工作副本中)
回退之后又想回去了:
先使用 git reflog
查看所有的操作,找到 commitID 再进行回退。
使用 revert 进行回退(查看 git log
,创建了一个新的提交):git revert <comit-id>
修改了文件,还没有执行 add,此时文件在工作区,回退到之前的版本:git checkout -- <file>
修改了文件,执行了 add ,此时文件在暂存区,回退:git reset HEAD <file>
配置
使用.giignore
文件,忽略不想要管理的文件。这里有模版 https://github.com/github/gitignore
文件别忽略了,也可以强制添加:git add -f target/
检查 .gitignore
是否有问题:git check-ignore -v .gitignore
配置别名:git config --global alias.st status
然后就可以使用 git st
代替 git status
了。
当前仓库的配置文件在 .git/config
文件中,全局的 git 配置文件在用户目录下的 .gitconfig
。
使用 git
- 一次提交仅仅对应一个相关的改动,不要把那些互相毫无关联的改动打包在同一次提交中。
- 不要提交不完整的改动,保存当前的工作用
git stash
。 - 每次提交都要详细的注释,说清楚:为什么要改?改了什么?。
- 养成频繁提交的习惯,避免很庞大的提交,这样也容易避免冲突的发生。
- 使用强大的分支,比如:开发新功能,修改 bug 等。
- 遵循一致的工作流程,比如:长期分支,特性分支,merge 还是 rebase 等。
- 使用帮助文档:
git help <command>
参考网站
可视化工具
SourceTree,跨平台,免费。
Tower,Mac 上非常出名的 git 工具,目前已经有 windows 版本,收费。