git 学习资料推荐廖雪峰https://www.liaoxuefeng.com/wiki/896043488029600
git库所在的文件夹中的文件大致有4种状态
-
Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过
git add
状态变为Staged
. -
Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为
Modified
. 如果使用git rm
移出版本库, 则成为Untracked
文件 -
Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过
git add
可进入暂存staged
状态, 使用git checkout
则丢弃修改过, 返回到unmodify
状态, 这个git checkout
即从库中取出文件, 覆盖当前修改 -
Staged: 暂存状态. 执行
git commit
则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify
状态. 执行git reset HEAD filename
取消暂存, 文件状态为Modified
下面的图很好的解释了这四种状态的转变:

新建文件--->Untracked
使用add命令将新建的文件加入到暂存区--->Staged
使用commit命令将暂存区的文件提交到本地仓库--->Unmodified
如果对Unmodified状态的文件进行修改---> modified
如果对Unmodified状态的文件进行remove操作--->Untracked
四个工作区域
Git本地有四个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)、git仓库(Remote Directory)。文件在这四个区域之间的转换关系如下:
Workspace: 工作区,就是你平时存放项目代码的地方
Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
git diff HEAD -- readme.txt
命令可以查看工作区和版本库里面最新版本的区别,HEAD指向的是版本库中的当前版本,而file指的是当前工作区中的文件。
$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. -Git tracks changes. (版本库) +Git tracks changes of files.(工作区)
回退本地仓库的上个版本
$ git reset --hard HEAD^ HEAD is now at e475afc add distributed
上面的意思是,HEAD指针指向了上个版本,然后顺便把工作区的文件更新了,因为是指针,所以回滚特别快
回退指定版本(只需指定commit id)
查看commit id (git log 或者 git reflog)
$ git reset --hard 1094a HEAD is now at 83b0afe append GPL
--------------
丢弃暂存区的修改(unstage),重新放回工作区git reset HEAD <file>:
$ git reset HEAD readme.txt Unstaged changes after reset: M readme.txt
然后
丢弃工作区的修改
$ git checkout -- readme.txt $ git status On branch master nothing to commit, working tree clean
---------------
git merge用法:
例如:把dev分支合并到master,先切换到master分支git switch master
用法1:git merge dev
看图:
$ git log --graph --pretty=oneline --abbrev-commit
* 62baf1c (HEAD -> master, dev) add oo
* 1469e02 Merge branch 'dev'
|\
| * 1d33f58 without no-ff
* | c149a14 dev merge master with --no-ff
用法2:git merge --no--ff -m "merge with no-ff bb" dev
看图:
$ git log --graph --pretty=oneline --abbrev-commit
* 270081e (HEAD -> master) merge with no-ff bb
|\
| * 3e911b1 (dev) add bb
|/
* 62baf1c add oo
* 1469e02 Merge branch 'dev'
综述:可以从这个(1469e02)commit id看, 方法1
git merge dev是fast-foward快进模式,直接把master指针移到dev,没有体现dev分支的merge过程
方法2git merge --no--ff -m "merge with no-ff bb" dev 禁用了快进模式,在提交历史中可以清楚看到dev分支合并过程
git cherry-pick
作用:免做重复工作
例如:现有分支dev,master;目前需要紧急修改个bug,所以基于master分支新建hotfix分支;修复bug然后提交(这里有个commit id,“351142e”)
然后merge到master进行发布;ok,既然master有bug,dev是基于master的,所以dev也有同样的bug;这时候你可以像改hotfix一样手动修改,但是我们崇尚不重复工作,
这时cherry-pick就能搞定了。
git switch dev
git cherry-pick351142e
然后查看git log就能看到这个提交记录,并在工作目录也更新了修复内容,perfect!
git branch -D <branch name> :强行删除一个未merge的分支
git reset --hard <commit id> :删除已经merge的提交,其实时回滚到相应的commit id,比如回到merge之前的commit,这样就相当于放弃了本次merge啦
git push origin master :此master为本地分支,默认时关联远端的master,如要推送dev分支到远端则:git push origin dev 也可以这样(git push -u origin dev 以后就可以简化成这样啦 git push但觉得不保险)
git push origin serverfix这里有些工作被简化了。 Git 自动将 serverfix
分支名字展开为 refs/heads/serverfix:refs/heads/serverfix
, 那意味着,“推送本地的 serverfix
分支来更新远程仓库上的 serverfix
分支。
如果并不想让远程仓库上的分支叫做 serverfix
,可以运行 git push origin serverfix:awesomebranch
来将本地的 serverfix
分支推送到远程仓库上的 awesomebranch
分支。
git push <远程主机名> <本地分支名>:<远程分支名>
git push origin master :此master为本地分支
git pull <远程主机名> <远程分支名>:<本地分支名>
git pull origin master :此master为远程分支
git rebase
rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
rebase操作可以把本地未push的分叉提交历史整理成直线;
git checkout -b dev origin/dev
一般来说
在目录下用git clone git@github.com:xxxxx/yyyyy.git
接着要查看下本地的当前分支嘛
git branch
你会看到你在master分支下
这个时候往往会用git checkout -b dev origin/dev这个命令
它意思是说.切换到dev分支上,接着跟远程的origin地址上的dev分支关联起来,这里要注意origin代表是一个路径,可以用git remote -v 查看
说来白了,origin/dev有点像是git@github.com:xxxxx/yyyyy.git/dev
接着在dev当前分支下进行操作,add,commit后,用git push origin dev,意思是推送当前的dev分支到远程origin地址的dev分支上
创建名为newbranch的分支
git checkout -b newbranch start_point
start_point是当前分支commit的点,一般是当前的HEAD,一般也不写 git checkout -b newbranch
git log 就可以对比commit内容