Git笔记

Published:

工作中使用到Git进行多人合作,之前都是自己独自开发,用到的只是Git的一点皮毛,需求到了,自然要学到更深的,看了下廖雪峰Git教程,自己做了下简易整理。

本地基本操作

无远程仓库时,可直接 git init 初始化本地仓库。

仓库可分为work区、stash区和HEAD区。之所以命名HEAD区,是因为commit实际上是更改HEAD的指针位置。

文件在各区移动:平时增删改文件均在work区进行,使用 git add filename 将文件从work区移动至stash区,使用 git commit -m "message" 将文件从stash区移动至HEAD区。

git status 可查看任一时刻的文件状态,git diff <filename> 可查看工作区和暂存区的文件改动。 git diff HEAD <filename> 可查看工作区和HEAD区的文件改动。

使用 git log 查看历史commit记录,使用 git reset --hard version 进行回退版本,version为 HEAD^ 表示当前版本的上个版本,HEAD^^ 则是上上个版本,依此类推。若要恢复版本回退,使用 git reflog 查看HEAD指针更改的历史。注意这里的回退和恢复会将work区和stash区全部重置。

使用 git checkout -- <filename> 可丢弃仅工作区的增删改查,恢复为stash区的状态 – 不能省略。 使用 git reset HEAD <filename> 可清除已添加至stash中的所有文件,工作区文件保持不变。

分支操作

这部分是公司工作必备的技能。上一版块讲述的所有操作都是在master分支上进行的,执行 git log –graph 也会发现至存在一条线,这条线便是HEAD指针所经过的所有位置。同一时刻仅有一个HEAD指针,可以指向不同分支。

使用git branch 查看当前仓库下的所有分支;使用git checkout -b dev相当于先后执行git branch devgit checkout dev,即创建并切换至dev分支,此时HEAD指针指向dev分支。

切换至dev分支后,在该工作区进行更改并add并commit,HEAD指针便在dev上进行移动,然后切换至master分支上,若在对dev更改的这段时间,master分支内容未进行冲突变化,那么可以直接在master分支上执行git merge dev,便使用ff(Fast-forward)模式进行合并,这样在merge之前的master分支和dev分支进行的变化都将统一到merge之后的master分支上,之后便可以执行git branch -d dev进行删除dev分支。

上面提到了在master和dev无冲突的情况下可以直接merge,当有冲突时,git会提示,此时进行更改冲突文件,改为你最终想让文本成为的样子,便可以在master分支上add commit,最后删除dev分支,可以使用git log --graph查看分支合并图。

上面提到了ff mode模式进行merge,另一个方式merge方式是使用形如git merge --no-ff -m "merge with no-ff message" dev的命令。以下是merge有无ff mode的区别:

However, occasionally you want to prevent this behavior from happening, typically because you want to maintain a specific branch topology (e.g. you’re merging in a topic branch and you want to ensure it looks that way when reading history). In order to do that, you can pass the –no-ff flag and git merge will always construct a merge instead of fast-forwarding. - StockOverflow

当在当前工作区进行文件更改导致无法切换分支,又暂时不能commit时,可以使用git stash命令将当前工作区做的更改存储起来,之后便可以切换到其它分支进行BUG修复等。然后再切换回来,使用git stash list查看所有保存了的工作现场,使用git stash pop恢复工作现场。

使用git branch -d <name>删除某分支,使用git branch -D <name>强制删除某分支。

标签是commit的id的替换,利于管理。使用git tag <name>为当前分支的当前HEAD指向的commit打标签,git tag查看当前分之下的所有标签,git tag <name> <commit-id>为指定的commit打标签,git show <tag-name>查看某标签的commit详情信息,git tag -d <tag-name>删除标签。

使用git push origin <tag-name>将某标签推送至远程仓库,git push origin --tags推送所有标签至远程仓库,先后执行git tag -d <tag-name>git push origin :refs/tags/<tag-name>删除远程仓库的标签。另外标签可视为release版本。

远程仓库

远程仓库上创建空的仓库,这里以github为例,创建空的repo:learngit,之后在本地learngit目录下执行 git remote add origin <remote-url>,便添加了远程仓库,默认远程仓库名字为origin,注意这里的origin是仓库的名字,此时使用git checkout -b <branch-name> origin/<branch-name>可在本地checkout出远程仓库的其他分支,本地和远程分支名称最好一致。使用git remote查看本地关联的远程仓库信息,git remote -v 查看详情信息。

多人协作的工作模式通常是这样:首先,可以试图用git push origin <branch-name>推送自己的修改;如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;如果合并有冲突,则解决冲突,并在本地提交;没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功,如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream <branch-name> origin/<branch-name>--set-upstream参数等价于-u)。