2. 仓库管理
2.1 本地仓库
使用Git来管理项目代码,就要创建本地仓库,在代码的项目根目录,输入:
$ git init
2.2 远程仓库
远程仓库是指托管在因特网或其他网络中的你的项目的版本库。你可以有好几个远程仓库,与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。
2.2.1 查看远程仓库
$ git remote -v origin git@github.com:AiJiangnan/spring-boot.git (fetch) origin git@github.com:AiJiangnan/spring-boot.git (push)
2.2.2 添加远程仓库
# git remote add <shortname> <url> $ git remote origin $ git remote add pb git@github.com:AiJiangnan/spring-boot.git $ git remote -v origin git@github.com:AiJiangnan/spring-boot.git (fetch) origin git@github.com:AiJiangnan/spring-boot.git (push) pb git@github.com:AiJiangnan/spring-boot.git (fetch) pb git@github.com:AiJiangnan/spring-boot.git (push)
2.2.3 从远程仓库中拉取和推送
# git fetch [remote-name] 抓取远程数据信息但不合并至当前工作 $ git fetch pb # git pull [remote-name] [branch-name] 抓取远程数据信息后合并至当前工作 $ git pull pb master # git push [remote-name] [branch-name] 推送当前分支修改至远程仓库 $ git push origin dev
中括号里面的参数表示可以省略,可以使用下面命令本地分支跟踪远程分支,跟踪后就可以拉取或推送的时候省略远程仓库名和分支名
$ git branch --set-upstream-to=origin/dev dev 分支 'dev' 设置为跟踪来自 'origin' 的远程分支 'dev'。
注意:
- 先有本地仓库,没有远程仓库。创建远程仓库后在本地添加远程仓库(
git remote add),本地的分支在远程不存在,第一次应将本地的分支推送至远程仓库。 - 先有远程仓库,本地没有代码。将代码克隆下来(
git clone),此时远程的分支信息都会克隆至本地。 - 一个远程仓库有多个开发人员维护,当别人在你之前推送了代码,应该先拉取代码且合并后再推送。
2.2.4 查看远程仓库
$ git remote show origin * 远程 origin 获取地址:git@github.com:AiJiangnan/spring-boot.git 推送地址:git@github.com:AiJiangnan/spring-boot.git HEAD 分支:master 远程分支: dev 已跟踪 master 已跟踪 为 'git pull' 配置的本地分支: dev 与远程 dev 合并 master 与远程 master 合并 为 'git push' 配置的本地引用: dev 推送至 dev (最新) master 推送至 master (最新)
2.2.5 远程仓库的移除和重命名
# 重命名远程仓库 $ git remote -v origin git@github.com:AiJiangnan/spring-boot.git (fetch) origin git@github.com:AiJiangnan/spring-boot.git (push) pb git@github.com:AiJiangnan/spring-boot.git (fetch) pb git@github.com:AiJiangnan/spring-boot.git (push) $ git remote rename pb bob $ git remote -v bob git@github.com:AiJiangnan/spring-boot.git (fetch) bob git@github.com:AiJiangnan/spring-boot.git (push) origin git@github.com:AiJiangnan/spring-boot.git (fetch) origin git@github.com:AiJiangnan/spring-boot.git (push) # 移除远程仓库 $ git remote rm bob $ git remote -v origin git@github.com:AiJiangnan/spring-boot.git (fetch) origin git@github.com:AiJiangnan/spring-boot.git (push)
3. 分支管理
不管是多人协作,还是保护开发主线,分支是一种很好的解决方案。
3.1 分支的新建与合并
3.1.1 新建分支
$ git branch dev $ git checkout dev $ git log --oneline --decorate ac705e4 (HEAD -> dev, master) update 4f9a890 update 52a10fa update master 0907ee4 update f3f5b5b add CONTRIBUTING.txt # 新建并切换至并新分支 $ git checkout -b dev
git log --decorate 命令查看各个分支当前所指的对象
3.1.2 合并分支
# 在dev分支上修改文件后切换至master分支进行合并 $ git checkout master 切换到分支 'master' $ git merge dev 更新 ac705e4..ae7e163 Fast-forward README.txt | 1 + 1 file changed, 1 insertion(+) $ git log --oneline --graph * ae7e163 (HEAD -> master, dev) update README.txt * ac705e4 update * 4f9a890 update * 52a10fa update master
3.1.3 解决冲突
# 在dev分支上修改文件并提交后切换至master分支修改同一文件提交后进行合并 $ git merge dev 自动合并 README.txt 冲突(内容):合并冲突于 README.txt 自动合并失败,修正冲突然后提交修正的结果。 $ git status -s UU README.txt # 使用编辑器解决好冲突并提交 $ git mergetool $ git log --oneline --graph * 63e8c22 (HEAD -> master) test merge by master * 758533c Merge branch 'dev' |\ | * ae7e163 update README.txt |/ * ac705e4 update * 4f9a890 update * 52a10fa update master # 合并有冲突时中断合并 $ git merge --abort
使用 git config --global merge.tool vimdiff 配置合并工具
3.2 分支管理
# 查看所有分支 $ git branch * dev master # 查看分支的最后一次提交 $ git branch -v * dev ffb9c7e update .gitignore master 1a44e48 Merge branch 'dev' # 查看已经合并至当前分支的分支 $ git branch --merged * dev # 查看未合并至当前分支的分支 $ git branch --no-merged master
前面带有*号的表示当前所在分支
3.3 分支开发工作流
3.3.1 长期分支
使用Git做开发最佳的工作方式,在默认分支master主分支上保留完全稳定的代码(已发布或者即将发布的代码),还有一些名为dev或test的平行分支,被用来后续开发或测试稳定性,这些分支不必保持绝对稳定,一旦达到稳定状态,它们就可以合并到master分支了。确保这些已开发完成的特性分支(短期分支),能够通过所有测试,并且不会引入更多bug之后,就可以合并入主分支中,等待下一次发布。
3.3.2 特性分支
特性分支是一种短期分支,被用来实现单一特性或其相关工作,这也对多人并行开发,或者多功能并行开发有着很大的好处。在别的版本控制系统(VCS)上创建和合并分支比较费劲,然而在Git中一天多次创建、使用、合并、删除分支都很常见。
注意:当你新建和合并分支的时候,所有这一切都只发生在你本地的Git版本库中,没有与服务器发生交互。
3.4 远程分支
3.4.1 推送
# 详情见 2.2.3 $ git push origin master # 抓取服务器分支信息 $ git fetch origin # 基于远程分支创建本地跟踪分支(设置本地分支与远程分支不同名字) $ git checkout -b develop origin/dev # 基于远程分支创建本地跟踪分支(设置本地分支与远程分支相同名字) $ git checkout --track origin/dev # 查看跟踪分支信息 $ git branch -vv
3.4.2 拉取
# 详情见 2.2.3 $ git pull origin dev
3.4.3 跟踪分支
# 详情见 2.2.3 $ git branch -u origin/dev $ git branch --set-upstream-to=origin/dev dev
3.4.4 删除远程分支
$ git push origin --delete hotfix
3.5 变基
在Git中整合来自不同的分支的修改主要有两种方法:merge和rebase。
3.5.1 变基操作
变基和合并结果没有任何区别,但是变基使得提交历史更加整洁。尽管实际的开发工作是并行的,但提交历史看上去就像串行的一样,提交历史是一条直线没有分叉。
# 变基 $ git checkout dev $ git rebase master # 变基后执行一次快进合并 $ git checkout master $ git merge dev
3.5.2 变基风险
注意:不要对在你的仓库外有副本的分支执行变基。
4. 存档管理
有时,当你在项目的一部分上已经工作一段时间后,而这时想要切换到另一个分支做一点别的事情,你又想提交当前没有做完的工作。此时,你可以使用git stash命令。修改的跟踪文件与暂存改动,然后将未完成的修改保存到一个栈上,而你可以在任何时候重新应用这些改动。
4.1 存档工作
# 修改几个文件 $ git status -s M CONTRIBUTING.txt M README.txt # 暂存一个改动 $ git add README.txt $ git status -s M CONTRIBUTING.txt M README.txt # 对当前的修改和暂存新建一个存档 $ git stash 保存工作目录和索引状态 WIP on master: 63e8c22 test merge by master # 此时工作目录是干净的 $ git status -s # 查看存档 $ git stash list stash@{0}: WIP on master: 63e8c22 test merge by master # 恢复存档(会丢失暂存,不删除存档) $ git stash apply 位于分支 master 尚未暂存以备提交的变更: (使用 "git add <文件>..." 更新要提交的内容) (使用 "git checkout -- <文件>..." 丢弃工作区的改动) 修改: CONTRIBUTING.txt 修改: README.txt 修改尚未加入提交(使用 "git add" 和/或 "git commit -a") $ git status -s M CONTRIBUTING.txt M README.txt # 恢复存档(不丢失暂存,不删除存档) $ git stash apply --index # 恢复存档(不丢失暂存,删除存档) $ git stash pop --index # 指定文件存档 $ git stash --patch # 存档中包含未跟踪文件(参数:-u|--include-untracked) $ git stash -u
4.2 删除存档
$ git stash list stash@{0}: WIP on master: 63e8c22 test merge by master $ git stash clear
4.2 从存档创建分支
$ git stash branch test
5. 标签管理
像其他版本控制系统(VCS)一样,Git可以给历史的某一个提交打上标签,人们会使用这个功能来标记发布结点(v1.0等等)。
5.1 列出标签
$ git tag v0.1 v1.3 # 筛选列出标签 $ git tag -l 'v1.8.5*' v1.8.5 v1.8.5-rc0 v1.8.5-rc1 v1.8.5.1
5.2 创建标签
5.2.1 附注标签
$ git tag -a v1.4 -m 'my version 1.4' # 查看标签信息和对应的提交信息 $ git show v1.4
5.2.2 轻量标签
$ git tag v1.4.1
5.2.3 后期打标签
$ git log --oneline 688bb11 (HEAD -> dev) test merge ae7e163 update README.txt ac705e4 update 4f9a890 update 52a10fa update master $ git tag -a v1.2 52a10fa
5.3 推送标签
$ git push origin v1.4 # 推送全部标签 $ git push origin --tags
5.4 检出标签
$ git checkout v1.4 # 检出并创建分支 $ git checkout -b version1 v1.0.0
6. 高效工具
6.1 交互式暂存
运行git add时使用参数-i或者--interactive,Git就会进入交互式终端模式。
$ git add -i staged unstaged path 1: unchanged +2/-0 CONTRIBUTING.txt 2: unchanged +2/-0 README.txt *** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now>
输入使用命令8查看帮助。
6.2 搜索
# 从提交历史中搜索字符串或正则表达式 参数:-n 显示行号 $ git grep Hello # 从提交历史中搜索提交记录 $ git log -SHello
6.3 重写历史
在使用Git时,可能会因为某些原因想要修正提交历史。
# 修改最后一次提交 $ git commit --amend # 修改多个提交信息 $ git rebase -i HEAD~3 # 将需要修改的提交前面的pick改为edit,保存退出 # 执行下面命令完成修改提交 $ git commit --amend $ git rebase --continue # 压缩提交 $ git rebase -i HEAD~3 # 将pick修改为squash,保存退出后编辑提交信息再保存退出
