-
0.使用GitHub
0.1 添加到远程库
0.2 从远程库克隆
0.3 GitHub使用 -
1.创建版本库
-
2.时光穿梭机
2.1 版本回退
2.2 工作区和暂存区
2.3 管理修改
2.4 撤销修改
2.5 删除文件 -
3.分支管理
3.1 创建与合并分支
3.2 解决冲突
3.3 分支管理策略
3.4 Bug分支
3.5 Feature分支
3.6 多人协作 -
4.标签管理
4.1 创建标签
4.2 操作标签 -
5.自定义Git
5.1 忽略特殊文件
5.2 配置别名
5.3 搭建Git服务器 -
6.扩展
6.1 rebase的使用
0.使用GitHub
生成SSH key,如果没有key的话,在用户主目录下面,执行下面语句:
ssh-keygen -t rsa -C "youremail@example.com"
该语句在用户主目录下面生成.ssh文件夹,文件夹中有两个文件,分别是id_rsa和id_rsa.pub,前者是私锁,不能告诉别人,后者是公锁,可以告诉别人,需要将后者即是id_rsa.pub中内容添加到GitHub的账户中,因为Git支持SSH协议,SSH key是GitHub用来识别代码是该用户提交过来的。
0.1 添加到远程库
git remote add origin https://github.com/Jayzen/demo_for_test.git
#远程库的名字叫做origin,是默认的远程库的名称,其中demo_for_test是用户自定义的仓库名称
git push -u origin master
#第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令
git push origin master #第二次之后远程库的代码提交(对比第一次提交少了-u 参数)
0.2 从远程库克隆
git clone https://github.com/Jayzen/gitskill.git #自己的电脑这个可行
git clone git@github.com:Jayzen/gitskill.git
0.3 GitHub使用
如果要修改一个开源库,步骤如下:
fork #fork一个项目,相当于在自己的github上面复制了一个相同的项目
git clone XX #在用户的本地复制该代码
git push #用户本地修改代码之后,推送到GiHub中用户本身的目录下面
pull request #发起这个pull request,看作者是否接受
具体示意图见如:
Paste_Image.png1.创建版本库
git init #初始化一个仓库
git add <file> #添加到仓库
git commit -m "some descriptions" #提交到仓库,其中后面显示的-m是对本次提交的一次说明
2.时光穿梭机
git status #查看用户的状态
#如果只是对代码进行了修改,之后没有做任何改动,则会显Changes not staged for commit
#如果是在当前文件夹内添加了一个文件,之后没有做任何动作,则会显示untracked files
#如果对文件进行了修改,执行了add,没有执行commit,则会显示Changes to be committed
#如果代码全部提交到仓库中,则会显示nothing to commit, working directory clean
git diff #查看代码做了哪些修改,这种状态修改的说明只能是该文件没有执行git add之前才能看到
2.1 版本回退
git log #显示从近到远的提交日志
git log --pretty=oneline #将这些日志按照行显示
git reset --hard HEAD^ #将版本退回到上一次提交,其中HEAD^表示上一个版本,HEAD^^表示上上一个版本
git reset --hard commit_id #其中commit_id是commit过程中生成的id值
git reflog #记录head指向的每一次命令
head指向append GPL
Paste_Image.png
改为head指向add distributed
Paste_Image.png2.2 工作区和暂存区
工作区其实就是git当前工作的文件夹。
把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
与此同时,在工作区中修改readme.txt文件和添加LICENSE,并且两次使用add命令,结果如下所示:
Paste_Image.png以上的结果可以看出,两次add方法是将文件添加到暂存区中,执行git commit -m "fourth commit",得到以下的结果,暂存区是干净的。
Paste_Image.png2.3 管理修改
Git跟踪的是修改,而不是文件。
git commit 提交给是是暂存区的内容,如果修改了文件,没有执行commit add,那么git commit对修改的文件内容无效。
git diff HEAD -- readme.txt #查看工作区和版本库里面最新版本的区别
2.4 撤销修改
第一种情况:在工作区中修改,当时没有提交到暂存区
git checkout --file
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
第二种情况:已经提交到暂存区
git reset HEAD file #可以把暂存区的修改撤销掉,重新放回工作区
git checkout --file #重复第一种情况
其中
git reset #命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
2.5 删除文件
当前工作区内有两个文件,分别是demo.rb和test.rb,其中在工作区中删除文件test.rb,则下面有两种情况:
#第一种:确实要删除该文件
git rm test.rb
git commit -m "remove test.rb"
自己测试了下,下面的代码也可以实现删除功能,因为版本控制跟踪的修改,而不是文件。
git add .
git commit -m "remove test.rb"
#第二种:
删除文件出现错误,因此相当于撤销修改
git checkout --test.rb #git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
3.1 创建和合并分支
git branch #查看分支
git branch <name> #创建分支
git checkout <name> #切换分支
git checkout -b <name> #创建+切换分支
git merge <name> #合并某分支到当前分支
git branch -d <name> #删除分支
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点,每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长:
Paste_Image.png当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:
Paste_Image.pngGit创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:
Paste_Image.png假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:
Paste_Image.png合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:
Paste_Image.png3.2 解决冲突
当主分支和从分支在同一个地方进行修改了,并且进行合并之后,出现了冲突。
#生成另外一个分支,对这个分支进行修改,然后提交
git checkout -b feature
修改demo.rb中的内容
git add demo.rb
git commit -m "commit feature"
#回到master分支,对master分支进行修改,然后提交
git checkout master
修改demo.rb中的内容,并且和上一个部分修改同一个地方
git add demo.rb
git commit -m "commit master"
#对两个分支进行合并
git merge feature #出现了conflict
#修改conflict的内容,重新进行提交
git add demo.rb
git commit -m "final commit"
#上面的内容对conflict内容进行了修改,并且在master分支上进行了合并成功
#删除分支
git branch -d feature
#用图像形式显示合并
git log --graph --pretty=oneline --abbrev-commit
3.3 分支管理策略
每个人不应该在master分支上建立分支,而应该在dev分支上建立分支,每次提交应该针对dev分支,当发布版本时应该从dev分支上提交到master分支
如果按照上文的合并方式(fast forward)进行的话,如果删除了分支,就会丢失分支信息,因此这里可以采用禁用Fast forward模式,Git就会在merge时生成一个新的commit。
git checkout -b dev
修改demo.rb文件内容
git add demo.rb
git commit -m "commit dev"
#切换到master分支,禁止fast forward模式
git checkout master
git merge --no-ff -m "merge with no-ff" dev
#查看log,可以看到分支信息
git log --graph --pretty=oneline --abbrev-commit
下面图片显示分支信息:
Paste_Image.png
3.4 Bug分支
Bug分支的策略是把当前的分支存储起来,然后建立bug分支,修复好之后再对当前分支进行恢复。
git status #当前分支下的内容
git stash #对当前分支进行存储
git status #当对当前分支进行存储之后,发现当前分支的status是空的
#对bug分支进行修复
git checkout master
git checkout -b bug-issue
对demo.rb文件内容进行修改
git add demo.rb
git commit -m "bug commit"
git checkout master
git merge --no-ff -m "merge bug commit" bug-issue
git status #查看工作目录是空的
git slash list #查看slash
git slash apply #恢复后,stash内容并不删除,你需要用git stash drop来删除
git stash apply stash@{0} #恢复指定的slash
git slash pop #恢复的同时把stash内容也删了
git slash list #恢复后查看slash的内容也没有了
3.5 Feature分支
如果是开发新功能,最好是新建一个分支,如果这个分支已经被合并,那么删除这个分支使用:
git branch -d feature
如果这个分支没有被合并,删除这个分支,需要用到下面的语句:
git branch -D feature
3.6 多人协作
从远程克隆仓库也是分多种情况,第一种情况是只有一个master分支的情况下:
git clone XX #远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin
git remote #origin 此代码是查看远程库的信息,远程库的默认信息是origin
git remote -v #使用-v查看远程库更为详细的信息
origin git@github.com:michaelliao/learngit.git (fetch)
origin git@github.com:michaelliao/learngit.git (push)
git push origin master #推送master分支
git push origin dev #推送dev分支
第二种情况是当远程库存在多个分支时候,使用git clone语句克隆代码,使用git branch语句只能查看master分支,为了显示其他分支,需要创建远程的origin的dev分支到本地:
git clone XX
git branch #master
#实际上被克隆的代码库有很多分支,而这里只能显示master分支
git checkout -b dev origin/dev
#使用上面的语句在本地建立dev分支,和远程库的dev分支对象起来,同时获得远程库的分支信息代码
#在dev分支上修改代码
git commit -m "add the dev"
git push origin dev #将代码推送到远程库dev分支中
第三情况是处理冲突:两个人同时写作同一个代码库,比如在feature分支上面,一个人已经作为修改,另外一个人在此人修改之前已经git clone到本地,并且在feature同一个地方做了修改,因此会出现conflict。
#已经有其他用户在feature分支上面建立test.rb文件
#下面的代码都是在本地的feature分支上进行
git add test.rb
git commit -m "add the test.rb"
git push origin feature
上面的代码出现错误,根据提示可以知道,是因为出现了代码冲突,根据提示使用git pull。
git pull #如果存在no tracking information,说明本地分支和远程分支之间的链接关系没有建立
git branch --set-upstream-to=origin/feature feature #设置feature和origin/feature的链接
git pull #出现冲突及冲突提示
#冲突解决好之后重新提交
git commit -m "conflict commit"
git push origin feature
4.标签管理
标签是版本库的一个快照,若给版本库打了一个标签,就相当于在某个时候获取一个特定时间的版本库,标签和分支不同,分支可以移动,标签不能移动。
4.1 创建标签
git checkout master #切换到最新的master分支上
git tag v1.0 #给最新的分支贴上标签
git tag #查看所有标签
默认情况下标签是打在最新的提交的commit上,如果需要打在之前提交的commit上,需要如下的语句
git log --pretty=oneline --abbrev-commit #显示commit id log
git tag v0.9 1234234 #其中1234234是commit id值,即将标签打在这个commit id中。
git show v1.0 #查看某个版本的标签
git tag -a v0.1 -m "version 0.1 released" 3628164
#创建带有说明的标签,用-a指定标签名,-m指定说明文字
4.2 操作标签
git tag -d v0.9 #删除标签
git push origin v0.9 #因为标签都是在本地的,此代码是推送标签到远程
git push origin --tags #一次性推送全部尚未推送到远程的本地标签
#如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
#然后,从远程删除。删除命令也是push
git tag -d v0.9
git push origin :refs/tags/v0.9
5.自定义Git
git config --global color.ui true #设置颜色
5.1 忽略特殊文件
在工作区建立 .gitignore
ruby的示例文件可以在这里找到
5.2 配置别名
配置别名就是在将Git的命令用其他名字来表示,示例代码如下所示:
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
#--global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。
每个仓库的Git配置文件都放在.git/config文件中,其中别名就在[alias]后面,要删除别名,直接把对应的行删掉即可。
[core]
repositoryformatversion = 0
filemode = true bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github.com:michaelliao/learngit.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[alias]
last = log -1
而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig
中:
[alias]
co = checkout
ci = commit
br = branch
st = status
[user]
name = Your Name
email = your@email.com
5.3 搭建Git服务器
见这里
6.扩展
6.1 rebase的使用
相关文档
在master分支上简历mywork分支,示意图如下所示:
在mywork分支上提交两次代码,同时其他用户在master分支上提交了两次代码,示意图如下所示:
Paste_Image.png在这里,你可以用"pull"命令把"origin"分支上的修改拉下来并且和你的修改合并; 结果看起来就像一个新的"合并的提交",示意图如下所示:
Paste_Image.png但是,如果你想让"mywork"分支历史看起来像没有经过任何合并一样,可以用git rebase,代码如下所示:
git checkout mywork
git rebase origin
这些命令会把你的"mywork"分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把"mywork"分支更新 到最新的"origin"分支,最后把保存的这些补丁应用到"mywork"分支上。
Paste_Image.png当'mywork'分支更新之后,它会指向这些新创建的提交(commit),而那些老的提交会被丢弃。 如果运行垃圾收集命令(pruning garbage collection), 这些被丢弃的提交就会删除。
Paste_Image.png现在我们可以看一下用合并(merge)和用rebase所产生的历史的区别:
Paste_Image.png6.2 修改最近一次的提交 commit --amend
该功能会修改最近一次的提交,使用commit --amend
比如最开始是这样的: git log
需要对添加add的讲解进行修改,使用下面代码:
git add .
git commit --amend
上面的代码会跳出一个编辑页面,可以修改添加add的讲解的值,修改为添加add和commit的讲解,并且进行保存,使用git log操作,可以得到如下的结果:
git log6.3 取消最新一次的提交 git revert head
下面的代码可以取消最近一次的提交
git revert HEAD
原本最初的提交branch如下所示:
Paste_Image.png执行git revert HEAD之后,变为如下的结果
Paste_Image.png就是说针对“添加pull的讲解”所变化的内容消失了。
6.4 使用reset来删除前面的几个提交
代码如下所示:
git reset --hard HEAD~~ #这是删除最前面的两个提交
git reset --hard HEAD~ #这是删除了最前面的一个提交
git reset --hard ORGI_HEAD #如果之前的reset出错了,该代码会返回最开始进行reset的位置
图片演示如下:
before reset after reset6.5 **使用cherry-pick将其他分支中的内容添加到主分支中 **
如下图所示:
-
0.使用GitHub
0.1 添加到远程库
0.2 从远程库克隆
0.3 GitHub使用 -
1.创建版本库
-
2.时光穿梭机
2.1 版本回退
2.2 工作区和暂存区
2.3 管理修改
2.4 撤销修改
2.5 删除文件 -
3.分支管理
3.1 创建与合并分支
3.2 解决冲突
3.3 分支管理策略
3.4 Bug分支
3.5 Feature分支
3.6 多人协作 -
4.标签管理
4.1 创建标签
4.2 操作标签 -
5.自定义Git
5.1 忽略特殊文件
5.2 配置别名
5.3 搭建Git服务器 -
6.扩展
6.1 rebase的使用
0.使用GitHub
生成SSH key,如果没有key的话,在用户主目录下面,执行下面语句:
ssh-keygen -t rsa -C "youremail@example.com"
该语句在用户主目录下面生成.ssh文件夹,文件夹中有两个文件,分别是id_rsa和id_rsa.pub,前者是私锁,不能告诉别人,后者是公锁,可以告诉别人,需要将后者即是id_rsa.pub中内容添加到GitHub的账户中,因为Git支持SSH协议,SSH key是GitHub用来识别代码是该用户提交过来的。
0.1 添加到远程库
git remote add origin https://github.com/Jayzen/demo_for_test.git
#远程库的名字叫做origin,是默认的远程库的名称,其中demo_for_test是用户自定义的仓库名称
git push -u origin master
#第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令
git push origin master #第二次之后远程库的代码提交(对比第一次提交少了-u 参数)
0.2 从远程库克隆
git clone https://github.com/Jayzen/gitskill.git #自己的电脑这个可行
git clone git@github.com:Jayzen/gitskill.git
0.3 GitHub使用
如果要修改一个开源库,步骤如下:
fork #fork一个项目,相当于在自己的github上面复制了一个相同的项目
git clone XX #在用户的本地复制该代码
git push #用户本地修改代码之后,推送到GiHub中用户本身的目录下面
pull request #发起这个pull request,看作者是否接受
具体示意图见如:
Paste_Image.png1.创建版本库
git init #初始化一个仓库
git add <file> #添加到仓库
git commit -m "some descriptions" #提交到仓库,其中后面显示的-m是对本次提交的一次说明
2.时光穿梭机
git status #查看用户的状态
#如果只是对代码进行了修改,之后没有做任何改动,则会显Changes not staged for commit
#如果是在当前文件夹内添加了一个文件,之后没有做任何动作,则会显示untracked files
#如果对文件进行了修改,执行了add,没有执行commit,则会显示Changes to be committed
#如果代码全部提交到仓库中,则会显示nothing to commit, working directory clean
git diff #查看代码做了哪些修改,这种状态修改的说明只能是该文件没有执行git add之前才能看到
2.1 版本回退
git log #显示从近到远的提交日志
git log --pretty=oneline #将这些日志按照行显示
git reset --hard HEAD^ #将版本退回到上一次提交,其中HEAD^表示上一个版本,HEAD^^表示上上一个版本
git reset --hard commit_id #其中commit_id是commit过程中生成的id值
git reflog #记录head指向的每一次命令
head指向append GPL
Paste_Image.png
改为head指向add distributed
Paste_Image.png2.2 工作区和暂存区
工作区其实就是git当前工作的文件夹。
把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
与此同时,在工作区中修改readme.txt文件和添加LICENSE,并且两次使用add命令,结果如下所示:
Paste_Image.png以上的结果可以看出,两次add方法是将文件添加到暂存区中,执行git commit -m "fourth commit",得到以下的结果,暂存区是干净的。
Paste_Image.png2.3 管理修改
Git跟踪的是修改,而不是文件。
git commit 提交给是是暂存区的内容,如果修改了文件,没有执行commit add,那么git commit对修改的文件内容无效。
git diff HEAD -- readme.txt #查看工作区和版本库里面最新版本的区别
2.4 撤销修改
第一种情况:在工作区中修改,当时没有提交到暂存区
git checkout --file
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
第二种情况:已经提交到暂存区
git reset HEAD file #可以把暂存区的修改撤销掉,重新放回工作区
git checkout --file #重复第一种情况
其中
git reset #命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
2.5 删除文件
当前工作区内有两个文件,分别是demo.rb和test.rb,其中在工作区中删除文件test.rb,则下面有两种情况:
#第一种:确实要删除该文件
git rm test.rb
git commit -m "remove test.rb"
自己测试了下,下面的代码也可以实现删除功能,因为版本控制跟踪的修改,而不是文件。
git add .
git commit -m "remove test.rb"
#第二种:
删除文件出现错误,因此相当于撤销修改
git checkout --test.rb #git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
3.1 创建和合并分支
git branch #查看分支
git branch <name> #创建分支
git checkout <name> #切换分支
git checkout -b <name> #创建+切换分支
git merge <name> #合并某分支到当前分支
git branch -d <name> #删除分支
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点,每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长:
Paste_Image.png当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:
Paste_Image.pngGit创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:
Paste_Image.png假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:
Paste_Image.png合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:
Paste_Image.png3.2 解决冲突
当主分支和从分支在同一个地方进行修改了,并且进行合并之后,出现了冲突。
#生成另外一个分支,对这个分支进行修改,然后提交
git checkout -b feature
修改demo.rb中的内容
git add demo.rb
git commit -m "commit feature"
#回到master分支,对master分支进行修改,然后提交
git checkout master
修改demo.rb中的内容,并且和上一个部分修改同一个地方
git add demo.rb
git commit -m "commit master"
#对两个分支进行合并
git merge feature #出现了conflict
#修改conflict的内容,重新进行提交
git add demo.rb
git commit -m "final commit"
#上面的内容对conflict内容进行了修改,并且在master分支上进行了合并成功
#删除分支
git branch -d feature
#用图像形式显示合并
git log --graph --pretty=oneline --abbrev-commit
3.3 分支管理策略
每个人不应该在master分支上建立分支,而应该在dev分支上建立分支,每次提交应该针对dev分支,当发布版本时应该从dev分支上提交到master分支
如果按照上文的合并方式(fast forward)进行的话,如果删除了分支,就会丢失分支信息,因此这里可以采用禁用Fast forward模式,Git就会在merge时生成一个新的commit。
git checkout -b dev
修改demo.rb文件内容
git add demo.rb
git commit -m "commit dev"
#切换到master分支,禁止fast forward模式
git checkout master
git merge --no-ff -m "merge with no-ff" dev
#查看log,可以看到分支信息
git log --graph --pretty=oneline --abbrev-commit
下面图片显示分支信息:
Paste_Image.png
3.4 Bug分支
Bug分支的策略是把当前的分支存储起来,然后建立bug分支,修复好之后再对当前分支进行恢复。
git status #当前分支下的内容
git stash #对当前分支进行存储
git status #当对当前分支进行存储之后,发现当前分支的status是空的
#对bug分支进行修复
git checkout master
git checkout -b bug-issue
对demo.rb文件内容进行修改
git add demo.rb
git commit -m "bug commit"
git checkout master
git merge --no-ff -m "merge bug commit" bug-issue
git status #查看工作目录是空的
git slash list #查看slash
git slash apply #恢复后,stash内容并不删除,你需要用git stash drop来删除
git stash apply stash@{0} #恢复指定的slash
git slash pop #恢复的同时把stash内容也删了
git slash list #恢复后查看slash的内容也没有了
3.5 Feature分支
如果是开发新功能,最好是新建一个分支,如果这个分支已经被合并,那么删除这个分支使用:
git branch -d feature
如果这个分支没有被合并,删除这个分支,需要用到下面的语句:
git branch -D feature
3.6 多人协作
从远程克隆仓库也是分多种情况,第一种情况是只有一个master分支的情况下:
git clone XX #远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin
git remote #origin 此代码是查看远程库的信息,远程库的默认信息是origin
git remote -v #使用-v查看远程库更为详细的信息
origin git@github.com:michaelliao/learngit.git (fetch)
origin git@github.com:michaelliao/learngit.git (push)
git push origin master #推送master分支
git push origin dev #推送dev分支
第二种情况是当远程库存在多个分支时候,使用git clone语句克隆代码,使用git branch语句只能查看master分支,为了显示其他分支,需要创建远程的origin的dev分支到本地:
git clone XX
git branch #master
#实际上被克隆的代码库有很多分支,而这里只能显示master分支
git checkout -b dev origin/dev
#使用上面的语句在本地建立dev分支,和远程库的dev分支对象起来,同时获得远程库的分支信息代码
#在dev分支上修改代码
git commit -m "add the dev"
git push origin dev #将代码推送到远程库dev分支中
第三情况是处理冲突:两个人同时写作同一个代码库,比如在feature分支上面,一个人已经作为修改,另外一个人在此人修改之前已经git clone到本地,并且在feature同一个地方做了修改,因此会出现conflict。
#已经有其他用户在feature分支上面建立test.rb文件
#下面的代码都是在本地的feature分支上进行
git add test.rb
git commit -m "add the test.rb"
git push origin feature
上面的代码出现错误,根据提示可以知道,是因为出现了代码冲突,根据提示使用git pull。
git pull #如果存在no tracking information,说明本地分支和远程分支之间的链接关系没有建立
git branch --set-upstream-to=origin/feature feature #设置feature和origin/feature的链接
git pull #出现冲突及冲突提示
#冲突解决好之后重新提交
git commit -m "conflict commit"
git push origin feature
4.标签管理
标签是版本库的一个快照,若给版本库打了一个标签,就相当于在某个时候获取一个特定时间的版本库,标签和分支不同,分支可以移动,标签不能移动。
4.1 创建标签
git checkout master #切换到最新的master分支上
git tag v1.0 #给最新的分支贴上标签
git tag #查看所有标签
默认情况下标签是打在最新的提交的commit上,如果需要打在之前提交的commit上,需要如下的语句
git log --pretty=oneline --abbrev-commit #显示commit id log
git tag v0.9 1234234 #其中1234234是commit id值,即将标签打在这个commit id中。
git show v1.0 #查看某个版本的标签
git tag -a v0.1 -m "version 0.1 released" 3628164
#创建带有说明的标签,用-a指定标签名,-m指定说明文字
4.2 操作标签
git tag -d v0.9 #删除标签
git push origin v0.9 #因为标签都是在本地的,此代码是推送标签到远程
git push origin --tags #一次性推送全部尚未推送到远程的本地标签
#如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
#然后,从远程删除。删除命令也是push
git tag -d v0.9
git push origin :refs/tags/v0.9
5.自定义Git
git config --global color.ui true #设置颜色
5.1 忽略特殊文件
在工作区建立 .gitignore
ruby的示例文件可以在这里找到
5.2 配置别名
配置别名就是在将Git的命令用其他名字来表示,示例代码如下所示:
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
#--global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。
每个仓库的Git配置文件都放在.git/config文件中,其中别名就在[alias]后面,要删除别名,直接把对应的行删掉即可。
[core]
repositoryformatversion = 0
filemode = true bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github.com:michaelliao/learngit.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[alias]
last = log -1
而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig
中:
[alias]
co = checkout
ci = commit
br = branch
st = status
[user]
name = Your Name
email = your@email.com
5.3 搭建Git服务器
见这里
6.扩展
6.1 rebase的使用
相关文档
在master分支上简历mywork分支,示意图如下所示:
在mywork分支上提交两次代码,同时其他用户在master分支上提交了两次代码,示意图如下所示:
Paste_Image.png在这里,你可以用"pull"命令把"origin"分支上的修改拉下来并且和你的修改合并; 结果看起来就像一个新的"合并的提交",示意图如下所示:
Paste_Image.png但是,如果你想让"mywork"分支历史看起来像没有经过任何合并一样,可以用git rebase,代码如下所示:
git checkout mywork
git rebase origin
这些命令会把你的"mywork"分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把"mywork"分支更新 到最新的"origin"分支,最后把保存的这些补丁应用到"mywork"分支上。
Paste_Image.png当'mywork'分支更新之后,它会指向这些新创建的提交(commit),而那些老的提交会被丢弃。 如果运行垃圾收集命令(pruning garbage collection), 这些被丢弃的提交就会删除。
Paste_Image.png现在我们可以看一下用合并(merge)和用rebase所产生的历史的区别:
Paste_Image.png6.2 修改最近一次的提交 commit --amend
该功能会修改最近一次的提交,使用commit --amend
比如最开始是这样的: git log
需要对添加add的讲解进行修改,使用下面代码:
git add .
git commit --amend
上面的代码会跳出一个编辑页面,可以修改添加add的讲解的值,修改为添加add和commit的讲解,并且进行保存,使用git log操作,可以得到如下的结果:
git log6.3 取消最新一次的提交 git revert head
下面的代码可以取消最近一次的提交
git revert HEAD
原本最初的提交branch如下所示:
Paste_Image.png执行git revert HEAD之后,变为如下的结果
Paste_Image.png就是说针对“添加pull的讲解”所变化的内容消失了。
6.4 使用reset来删除前面的几个提交
代码如下所示:
git reset --hard HEAD~~ #这是删除最前面的两个提交
git reset --hard HEAD~ #这是删除了最前面的一个提交
git reset --hard ORGI_HEAD #如果之前的reset出错了,该代码会返回最开始进行reset的位置
图片演示如下:
before reset after reset6.5 **使用cherry-pick将其他分支中的内容添加到主分支中 **
如下图所示:
将添加commit的讲解添加到master分支中,代码如下所示:
git checkout master
git cherry-pick 99daed2
#下面的提示代码是正常现象,说明提交成功
error: could not apply 99daed2... commit
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
#但是如果出现冲突的话,需要添加如下的进行如下的操作
git add filename
git commit
6.6 **使用rebase -i 汇合提交 **
这是做的事情是讲master上面最近的两次进行合并,汇合为一次提交,使用的代码如下:
git rebase -i HEAD~~
#上面的代码执行之后,会有下面的代码界面出现,将第二行的pick改为squash
pick 9a54fd4 添加commit的说明
pick 0d4a808 添加pull的说明
# Rebase 326fc9f..0d4a808 onto d286baa
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#编辑保存退出,然后出现了编辑界面,编辑里面的值,该值将成为合并commit的说明
示意图如下所示:
Paste_Image.png就是将添加commit的讲解和添加pull的讲解进行合并,成为一个commit。示意图如下所示: Paste_Image.png
6.7 用rebase -i 修改提交
在这里修改添加commit的讲解
代码修改如下所示:
git rebase -i HEAD~~
将第一行的pick改为eidt,保存之后退出
pick 9a54fd4 添加commit的说明
pick 0d4a808 添加pull的说明
# Rebase 326fc9f..0d4a808 onto d286baa
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
#打开sample.txt,适当地修改“commit的讲解”部分
git add sample.txt
git commit --amend
#已经commit,但是rebase操作还没结束。若要通知这个提交的操作已经结束,请指定 --continue选项执行rebase。
git rebase --continue
6.8 把分支内容合并成一个提交,并导入到master分支
示意图如下所示:
把下面的一个分支合并成一个提交,并导入的master分支中,具体的代码如下所示:
git checkout master
git merge --squash issue1
#出现了下面的提示,说明提交成功
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
#出现下面的提示,则说明提交失败,出现了冲突
Auto-merging sample.txt
CONFLICT (content): Merge conflict in sample.txt
Squash commit -- not updating HEAD
Automatic merge failed;
fix conflicts and then commit the result.
#说明发生了冲突,修改之后进行提交
git add sample.txt
git commit
6.9使用二分法查找bug
二分法的原理
代码演示如下:
git bisect start master commit_id #master是bad点,commit_id是最开始提交点
git bisect run make test #进行了自动化测试,此代码可以测试出错误点
网友评论