常用的git指令
同步仓库最新状态并合并
a) git pull: 从远程获取最新版本并merge到本地仓库(git fetch+git merge)
git pull <远程库名> <远程分支名>:<本地分支名>
git pull origin dev
或
b)
1.同步到仓库最新状态
git fetch <远程库名> <远程分支名>:<本地分支名>
git fetch origin dev
2.merge或rebase
git checkout dev
git merge origin/dev
git checkout dev
git rebase origin/dev
git merge 与 git rebase的区别
- git merge
- git rebase
冲突解决git merge & git rebase
git merge
- 通过git state发现冲突文件readme.txt
- 修改readme.tx后,git add readme.txt
- 提交git commit -m ‘conflict fixed’
git rebase
上传到github仓库
git push <远程主机名> <本地分支名>:<远程分支名>
# 建立关联,设置本体(origin)为[email protected]:doublespending/gitTest.git
git remote add origin git@github.com:doublespending/gitTest.git
# 上传本地分支dev到相应的origin上的dev分支,不存在则新建
git push -u origin dev
工作区&暂存区&版本库的操作
- 修改:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout – file。
2 .修改:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,在用git checkout – file - 修改:已经提交了不合适的修改到版本库时,想要撤销本次提交,要用 git reset – hard commit_id (^HEAD) 来版本回退
- git rm用于你确认删除一个文件
所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。
工作区/暂存区/版本库
本地仓库
# 设置个人信息
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
# 把这个目录变成Git可以管理的仓库
git init
# 把文件file1, file2, file3添加到仓库,实际上就是把文件修改添加到暂存区
git add file1
git add file2 file3
# 把三个文件提交至仓库并写上注释"add 3 files.",实际上就是把暂存区的所有内容提交到当前分支
git commit -m "add 3 files."
# 需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
# 修改README.md后,通过git status命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。
git status
# git diff告诉我们仓库下文件的修改情况
git diff
git diff README.md
git diff 比较的是工作区和暂存区的差别
git diff --cached 比较的是暂存区和版本库的差别
git diff HEAD 可以查看工作区和版本库的差别
# 添加到仓库
git add README.md
# 提交至仓库前查看情况
git status
# 提交至仓库
git commit -m "modify something"
git status
# 查看修改的历史记录
git log
git log --pretty=oneline
# 回退到上一个版本HEAD^,上上个版本HEAD^^
git reset --hard HEAD^
# 最新版本的信息不见了
git log
# 回到最新版本
git reset --hard 最新版本id的前几位
# 记录每一次命令,以及commit的id
git reflog
# 让README.md回到最近一次git commit或git add时的状态,"--"很重要
git checkout -- README.md
# 当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改
git reset HEAD README.md # 清空暂存区
git checkout -- README.md
# 在工作空间以及版本库中删除TEST.md
git rm TEST.md
git commit -m "remove TEST.md"
合并多个提交(commit)
gitk
gitk 是一个历史记录的图形化查看器,你可以把它当作是基于 git log 和 git grep 命令的一个强大的图形操作界面,当你需要查找过去发生的某次记录,或是可视化查看项目历史的时候,你将会用到这个工具。
gitk
远程仓库
SSH Key
ssh-keygen -t rsa -C "[email protected]"
把生成的公钥(id_rsa.pub)拷贝到github上。
关联远程库
git remote add origin git@server-name:path/repo-name.git;
第一次推送master分支的所有内容至远程库
把本地库的内容推送到远程,用git push命令,上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
git push -u origin master
推送新修改
git push origin master
从远程库克隆
git clone (ssh/https link)
创建与合并分支
创建dev分支,然后i切换到dev分支
git checkout -b dev
# git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
git branch dev
git checkout dev
查看当前分支
git branch
把指定分支(dev)的工作成果合并到当前分支(master)分支上
git merge dev
git merge的参数
--no-ff指的是强行关闭fast-forward方式。
fast-forward方式就是当条件允许的时候,git直接把HEAD指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建commit
git merge --squash 是用来把一些不必要commit进行压缩,比如说,你的feature在开发的时候写的commit很乱,那么我们合并的时候不希望把这些历史commit带过来,于是使用--squash进行合并,此时文件已经同合并后一样了,但不移动HEAD,不提交。需要进行一次额外的commit来“总结”一下,然后完成最终的合并。
总结:
--no-ff:不使用fast-forward方式合并,保留分支的commit历史
--squash:使用squash方式合并,把多次分支commit历史压缩为一次
–no-ff 图解:可以发现git merge是直接把HEAD指到feature分支上,而git merge –no-ff会把merge作为一次commit。所以左边有3+1=4个,右边有3个。
删除dev分支
git branch -d dev
解决冲突
git merge 两个有冲突的分支,可以用git status得知有冲突的文件
git status
可以用cat输出冲突文件可以得到下面的
HAHA!
<<<<<<< HEAD
& simple
=======
AND simple!
>>>>>>> featurel
情景
一般解决冲突的步骤是:
- 先本地直接提交代码:git push origin master
- 如果别人在自己之前提交了修改,git会提示push失败,需要先pull远程代码:git pull origin/master (拉取远程仓库进行自动合并)
- 如果能自动合并,git会提示auto merge成功,这时可以直接git push origin master
- 如果不能自动merge,git会提示auto merge失败,需要手动解决冲突:
- git status 查看冲突情况
- 修改冲突
- git add .
- git commit -m ‘解决冲突的注释说明’
- git push origin master
查看分支合并图
git log --graph
分支策略
Bug分支
checkout转换分支时,我们需要用的git stash进行保存工作区和暂存区,因为我们切换checkout的时候会覆盖掉当前的内容。
git checkout -b dev
do some work (with no commit)
git stash
git checkout -b bug
fix bug
git commit -m "fix bug"
git checkout dev
git stash pop