Git workflow
大神镇楼:
这人不用说。应该都认识,他基本干了两件事,一个是Linux。一个就是git。每一件事,都在IT史上创建了一个巨大的Tag。
Git是什么
Git能干什么?
Git用来做版本号控制,这就好比当初在小日本的公司,每次改动文件,都须要在文件第一页新增改动履历。具体记录改动内容,假设多人同一时候操作。你能够想象下维护的成本有多高。基本每天就在整理这些破事。
所以说,版本号控制是项目开发的重中之重。那么问题来了。版本号控制哪家强?一句话。Git是眼下世界上最先进的分布式版本号控制系统(没有之中的一个)。事实上也能够把分布式三个字去掉。
集中式版本号控制
集中式的版本号控制工具以SVN为代表,他有一个中央server。控制着全部的版本号管理。其它全部的终端。能够对这个中央库进行操作。中央库保证版本号的唯一性。
这样有一个很不好的地方,就是假设中央server被天灾军团攻陷了,那么整个版本号就gg了。由于终端仅仅能对一部分代码进行改动,获取各种信息,须要不断与中央server通信。
- 容灾性差
- 通信频繁
分布式版本号控制
分布式版本号控制的典型,就是Git。它跟集中式的最大差别就是它的终端能够获取到中央server的完整信息,就好像做了一个完整的镜像。这样,我能够在终端做各种操作、获取各种信息而不须要与server通信,同一时候,就算server被炸,各个终端还有完整的备份。
分布式的思路,在版本号控制上,具有得天独厚的优势,当然。这仅仅是git优势的冰山一角。
Git安装与配置
安装
Git的安装就不解释了,相信程序员都有能力独立解决这样一个问题,Linux和Mac下基本都已经自带Git了,window,建议不要用Git了。命令行实在是受不了。
配置
在终端输入:
➜ ~ git --version
git version 1.8.4
来查看当前Git的版本号,同一时候,输入:
➜ ~ git config --list --global
user.name=xuyisheng
user.email=xuyisheng@hujiang.com
push.default=current
或者:
➜ ~ git config user.name
xuyisheng
用来查看当前的配置信息。假设是新安装的,那么须要对global信息进行配置。配置的方法有两种,一个个变量配置,或者一起配置:
单独配置:
➜ ~ git config --global user.name xys
一起配置:
➜ ~ git config --global --add user.name xys
添加多个键值对
删除配置
➜ ~ git config --global --unset user.name xys
配置别名
这个功能在shell中是很经常使用的。我们能够做一些别名来代替比較复杂的指令。
比方:
git config --global alias.st status
我们使用st来代替status。
附上一个比較吊的:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
PS:用git log –graph命令能够看到分支合并图。
配置文件
git的配置文件事实上我们是能够找到的,就在.git文件夹下:
➜ testGit git:(master) ls -a
. .. .git README.txt
➜ testGit git:(master) cd .git
➜ .git git:(master) ls
HEAD description index logs packed-refs
config hooks info objects refs
➜ .git git:(master)
我们打开config文件:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = false
[remote "origin"]
url = git@github.com:xuyisheng/testGit.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "dev"]
remote = origin
merge = refs/heads/dev
这里就是我们全部的配置了。
创建Git仓库
版本号控制就是为了管理代码,代码就要放在仓库中。创建仓库有二种方法:
Git init
➜ MyWork mkdir gitTest
➜ MyWork cd gitTest
➜ gitTest git init
Initialized empty Git repository in /Users/hj/Downloads/MyWork/gitTest/.git/
➜ gitTest git:(master)
创建一个文件夹,并cd到文件夹下,通过调用git init来将现有文件夹初始化为git仓库,或者直接在git init后面跟上文件夹名。相同也能够创建一个新的仓库。
git clone
git clone用于clone一个远程仓库到本地。这个我们后面再将。
创建好仓库后。文件夹下会生成一个.git的隐藏文件夹,这里就是全部的版本号记录。默认不要对这个文件夹进行改动。
提交改动
add && commit
在仓库中,我们创建代码,并将其提交:
➜ gitTest git:(master) touch README.txt
➜ gitTest git:(master) ✗ open README.txt
➜ gitTest git:(master) ✗ git add README.txt
➜ gitTest git:(master) ✗ git commit -m "add readme"
[master (root-commit) c19081b] add readme
1 file changed, 1 insertion(+)
create mode 100644 README.txt
我们创建了一个README文件,并通过git add <文件名称>的方式进行add操作,最后通过git commit操作进行提交,-m參数,指定了提交的说明。
这两个命令应该是最常使用的git命令。
查看改动
在版本号控制中,很核心的一点,就是须要指定,我们做了哪些改动,比方之前我们创建了一个README文件,并在里面写了一句话:
this is readme。
以下我们改动这个文件:
this is readme。modify。
接下来,我们使用git status命令来查看当前git仓库哪些内容被改动了:
➜ gitTest git:(master) git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
我们能够发现,git提示我们:
modified: README.txt,更进一步。我们能够使用git diff命令来查看具体的改动:
diff --git a/README.txt b/README.txt
index 2744f40..f312f1a 100644
--- a/README.txt
+++ b/README.txt
@@ -1 +1 @@
-this is readme
No newline at end of file
+this is readme, modify
No newline at end of file
(END)
这样就查看了具体的改动。
以下我们继续add、commit:
➜ gitTest git:(master) ✗ git add README.txt
➜ gitTest git:(master) ✗ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README.txt
#
➜ gitTest git:(master) ✗ git commit -m "modify readme"
[master 1629cdc] modify readme
1 file changed, 1 insertion(+), 1 deletion(-)
➜ gitTest git:(master) git status
# On branch master
nothing to commit, working directory clean
add和commit之后,我们都使用status来查看下状态。能够发现。在commit之后,git提示我们,工作区是干净的。
版本号记录
在项目中,一个仓库通常可能有许多次的add、commit过程,这些记录都会被记录下来,我们能够使用git log来查看这些记录:
commit 1629cdcf2307bf26c0c5467e10035c2bd751e9d0
Author: xuyisheng <xuyisheng@hujiang.com>
Date: Sun Jun 28 14:45:14 2015 +0800
modify readme
commit c19081b6a48bcd6fb243560dafc7a35ae5e74765
Author: xuyisheng <xuyisheng@hujiang.com>
Date: Sun Jun 28 14:35:00 2015 +0800
add readme
(END)
每条记录都相应一个commit id,这是一个40个16进制的sha-1 hash code。
用来唯一标识一个commit。
同一时候,我们也能够使用gitk命令来查看图形化的log记录:
git会自己主动将commit串成一个时间线。
每一个点,就代表一个commit。点击这些点。就能够看见相应的改动信息。
工作区与暂存区
Git一般是工作在三个区域上:
- 工作区
- 暂存区
- 历史区
当中工作区就是我们平时工作、改动代码的区域,而历史区,用来保存各个版本号,而暂存区。则是Git的核心所在。
暂存区保存在我们前面讲的那个.git的隐藏文件夹中,是一个叫index的文件。
当我们向Git仓库提交代码的时候。add操作实际上是将改动记录到暂存区,我们来看gitk:
能够发现,我们在本地已经生成了一个记录,可是还没有commit,所以当前HEAD并没有指向我们的改动。改动还保存在暂存区。
当我们commit之后,再看gitk:
这时候,HEAD就已经移到了我们的改动上。也就是说,我们的提交生成了一个新的commit。git commit操作就是将暂存区的内容全部提交。
假设内容不add到暂存区,那么commit就不会提交改动内容。
PS 这里须要说明一个概念,git管理的是改动,而不是文件。每一个sha-1的值,也是依据内容计算出来的。
版本号回退
假设这个世界一直仅仅须要git add、commit。就不会有这么多的问题了。可是。愿望是美好的,现实是残酷的。怎样处理版本号的回退和改动,是使用git很重要的一步。
checkout && reset
我们来考虑几种情况:
- 文件已经改动,可是还没有git add
- 文件已经add到暂存区,又作了改动
- 文件的改动已经add到了暂存区
分别运行以下操作:
➜ gitTest git:(master) ✗ git checkout -- README.txt
- 改动被删除。全然还原到上次commit的状态,也就是server版本号
- 最后的改动被删除。还原到上次add的状态,也就是改动前的暂存区状态
总的来说。就是还原到上次add、commit的状态。
而对于第三种情况,我们能够使用git reset:
➜ gitTest git:(master) ✗ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README.txt
#
➜ gitTest git:(master) ✗ git reset HEAD README.txt
Unstaged changes after reset:
M README.txt
➜ gitTest git:(master) ✗ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
通过git reset HEAD README.txt,我们就把暂存区的文件清除了。这样,在本地就是add前的状态。通过checkout操作,就能够进行改动回退了。
PS : git checkout事实上是用版本号库里的版本号替换工作区的版本号,不管工作区是改动还是删除
回退版本号
当我们的仓库有了大量的提交的时候,我们能够通过git log来查看(能够指定 –pretty=oneline 来优化显示效果)。
e7ae095cafc8ddc5fda5a5d8b23d0bcaaf74ac39 modify again
5427c66703abfeaba3706f938317251ef2567e8b delete test.txt
08098a21a918cfbd6377fc7a03a08cac0e6bcef6 add new file
b687b06fbb66da68bf8e0616c8049f194f03a062 e
8038c502e6f5cbf34c8096eb27feec682b75410b update
34ad1c36b97f090fdf3191f51e149b404c86e72f modify again
1629cdcf2307bf26c0c5467e10035c2bd751e9d0 modify readme
c19081b6a48bcd6fb243560dafc7a35ae5e74765 add readme
那么我们假设回退到指定版本号呢?在Git中,用HEAD表示当前版本号,上一个版本号就是HEAD^。上上一个版本号就是HEAD^^,当然往上100个版本号就不要这样写了,写成HEAD~100就可以。
以下我们就能够回退了:
➜ testGit git:(master) git reset --hard HEAD^
HEAD is now at 5427c66 delete test.txt
要回退到哪个版本号。仅仅要HEAD写对就OK了。你能够写commit id,也能够HEAD^,也能够HEAD^^。
前进版本号
有时候。假设我们回退到了旧的版本号,可是却懊悔了。想回到后面某个新的版本号。但这个时候,我的commit id已经忘了,怎么办呢?
没事,通过这个指令:
5427c66 HEAD@{0}: reset: moving to HEAD^
e7ae095 HEAD@{1}: checkout: moving from dev to master
7986a59 HEAD@{2}: checkout: moving from master to dev
e7ae095 HEAD@{3}: checkout: moving from dev to master
7986a59 HEAD@{4}: checkout: moving from 7986a59bd8683acb560e56ff222324cd49edb5e5 to dev
7986a59 HEAD@{5}: checkout: moving from master to origin/dev
e7ae095 HEAD@{6}: clone: from git@github.com:xuyisheng/testGit.git
这样我们就能够找到commit id用来还原了。
git reflog记录的就是你的操作历史。
文件操作
git rm
假设我们要删除git仓库中的文件,我们要怎么做呢?
我们创建一个新的文件并提交,再删除这个文件:
➜ gitTest git:(master) rm test.txt
➜ gitTest git:(master) ✗ git status
# On branch master
# Changes not staged for commit:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: test.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
git提示我们delete一个文件。这时候你能够选择:
➜ gitTest git:(master) ✗ git checkout test.txt
这样就撤销了删除操作。或者使用:
➜ gitTest git:(master) ✗ git rm test.txt
rm 'test.txt'
➜ gitTest git:(master) ✗ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: test.txt
#
➜ gitTest git:(master) ✗ git commit -m "delete test.txt"
[master 5427c66] delete test.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 test.txt
通过git rm指令,删除文件,最后提交改动。就真实的删除了文件。
文件暂存
这里的暂存不是前面说的暂存区。而是仅仅一次备份与恢复操作。举个样例,当前我们在dev分支上进行一个新功能的开发,可是开发到一半,測试提了一个issue,这时候。我们须要创建一个issue分支来改动这个bug。可是,当前dev分支是不干净的。新功能开发到一半,直接从dev上拉分支,代码是不完好的,可能会编译只是。
so,你能够使用:
git stash
指令来将当前改动暂存,这样就能够切换到其它分支或者就在当前干净的分支上checkout了。
比方你checkout了一个issue分支,改动了bug。使用git merge合并到了master分支,删除issue分支,切换到dev分支。想继续之前的新功能开发。
这时候。就须要恢复现场了:
首先。通过:
git stash list
我们能够查看当前暂存的内容记录。
然后,通过git stash apply或者git stash pop来进行恢复,它们的差别是,前者不会删除记录(当然你能够使用git stash drop来删除)。而后者会。
远程仓库
既然git是分布式的仓库管理,那么我们肯定是须要多台server进行各种操作的,一般在开发中。我们会用一台电脑做中央server。各个终端从中央server拉代替码。提交改动。
那么我们怎样去搭建一个git远程server呢,答案是不要搭建。个人开发人员能够通过github来获取免费的远程gitserver,或者是国内的开源中国之类的,相同也提供免费的gitserver,而对于企业用户,能够通过gitlab来获取git远程server。
身份认证
当本地git仓库与git远程仓库通信的时候。须要进行SSH身份认证。
打开根文件夹下的.ssh文件夹:
➜ ~ cd .ssh
➜ .ssh ll
total 40
-rw------- 1 xys staff 1.7K 5 15 23:53 github_rsa
-rw-r--r-- 1 xys staff 402B 5 15 23:53 github_rsa.pub
-rw------- 1 xys staff 1.6K 5 15 09:38 id_rsa
-rw-r--r-- 1 xys staff 409B 5 15 09:42 id_rsa.pub
-rw-r--r-- 1 xys staff 2.0K 6 3 13:34 known_hosts
假设没有id_rsa和id_rsa.pub这两个文件。就通过例如以下的命令生成:
ssh-keygen -t rsa -C "youremail@example.com"
id_rsa和id_rsa.pub这两个文件,就是SSH Key的秘钥对,id_rsa是私钥。不能泄露出去。id_rsa.pub是公钥,用在github上表明身份。
在github的ssh key中添加刚刚生成的key:
同步协作
如今你在本地建立了git仓库。想与远程git仓库同步。这样github的远程仓库能够作为你本地的备份,也能够让其它人进行协同工作。
我们先在github上创建一个repo(仓库):
创建之后,github给我们提示:
github告诉了我们怎样在本地创建一个新的repo或者将既存的repo提交到远程git。
由于我们已经有了本地的git。所以,安装提示:
➜ gitTest git:(master) git remote add origin git@github.com:xuyisheng/testGit.git
➜ gitTest git:(master) git push -u origin master
Counting objects: 18, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (18/18), 1.39 KiB | 0 bytes/s, done.
Total 18 (delta 1), reused 0 (delta 0)
To git@github.com:xuyisheng/testGit.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
如今我们再看github上的仓库:
README已经提交上去了。
git remote add origin git@github.com:xuyisheng/testGit.git这条指令中的origin,就是远程仓库的名字,你也能够叫别的,可是默认远程仓库都叫做origin,便于区分。
PS: 这里还须要注意下的是git push的-u參数,加上了-u參数。Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来。只是后面的push就不须要这个參数了。
之后我们再做改动:
➜ gitTest git:(master) ✗ git add README.txt
➜ gitTest git:(master) ✗ git commit -m "modify again"
[master e7ae095] modify again
1 file changed, 2 insertions(+), 1 deletion(-)
➜ gitTest git:(master) git push
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 285 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:xuyisheng/testGit.git
5427c66..e7ae095 master -> master
能够直接使用git push或者git push origin master来指定仓库和分支名。
clone远程仓库
记得我们之前说的,创建本地仓库的几种方式,当中有一种是clone:
我们能够通过git clone指令来clone一个远程仓库:
以下就显示了远程仓库的地址,一般我们使用SSH的方式,当然。也能够使用其它方式,然并卵。
PS: 使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,可是在某些仅仅开放httpport的公司内部就无法使用ssh协议而仅仅能用https。
直接使用:
➜ MyWork git clone git@github.com:xuyisheng/testGit.git
Cloning into 'testGit'...
remote: Counting objects: 21, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 21 (delta 1), reused 21 (delta 1), pack-reused 0
Receiving objects: 100% (21/21), done.
Resolving deltas: 100% (1/1), done.
Checking connectivity... done
分支管理
个人觉得,创建分支是git最大的魅力。
git中的分支就好像如今的平行宇宙,不同的分支互不干扰,相互独立,你就像一个上帝一样,能够随时对随意一个分支进行操作,能够今天去这个branch玩。明天去还有一个branch,玩腻了,再把两个分支合并,一起玩。
举个比較恰当的样例,我如今要开发一个新功能。须要3个月的时间,可是我不能每天都把未完成的代码提交到大家都在用的分支上,这样人家拉取了我的代码就无法正常工作了。可是我又不能新建一个仓库,这也太浪费了,所以我能够新建一个分支,在这个分支上开发我的功能,同一时候能够备份我的代码。当开发完成后,直接合并分支。整个新功能就一下子添加了大家的分支。
创建分支
你的每次提交。Git都把它们串成一条时间线,这条时间线就是一个分支。不创建分支时。仅仅有一条时间线。在Git里。这个分支叫主分支。即master分支。HEAD严格来说不是指向提交。而是指向master,master才是指向提交的。所以,HEAD指向的就是当前分支。
这里的时间线就看的很清楚了。
我们通过例如以下指令来创建分支:
➜ gitTest git:(master) git checkout -b dev
Switched to a new branch 'dev'
➜ gitTest git:(dev)
-b參数代表创建并切换到该分支,相当于:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
不加-b參数就是直接切换到已知分支了。
查看分支
通过git branch指令能够列出当前全部分支:
➜ gitTest git:(dev) git branch
* dev
master
当前分支上会多一个*
合并分支
切换到dev分支后。我们进行改动。add并commit:
此时我们再切换到master分支,再查看当前改动,你会发现。dev分支上做的改动这里都没有生效。
必须的,不然平行宇宙就不平行了。
我们通过例如以下指令来进行分支的合并:
➜ gitTest git:(master) git merge dev
Updating e7ae095..7986a59
Fast-forward
README.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
这样再查看master分支下的文件,dev上的改动就有了。
删除分支
使用完成后,我们不再须要这个分支了,所以,放心的删除吧:
➜ gitTest git:(master) git branch -d dev
Deleted branch dev (was 7986a59).
➜ gitTest git:(master) git branch
* master
PS : 当分支还没有被合并的时候,假设删除分支,git会提示:
error: The branch ‘feature-vulcan’ is not fully merged.
If you are sure you want to delete it, run ‘git branch -D dev.
也就是提示我们使用-D參数来进行强行删除。
看完分支的操作。有人可能会问。创建这么多分支,git会不会很累,当然不会,git并非创建整个文件的备份到各个分支。而是创建一个指针指向不同的分支而已。切换分支,创建分支,都仅仅是改变指针指向的位置。
分支是很好的团体协作方式,一个项目中一般会有一个master分支来进行公布管理。一个dev分支来进行开发,而不同的开发人员checkout出dev分支来进行开发。merge自己的分支到dev,当有issue或者新需求的时候,checkout分支进行改动,能够保证主分支的安全,即使改动取消。也不会影响主分支。
查看远程分支
当你从远程仓库克隆时,实际上Git自己主动把本地的master分支和远程的master分支相应起来了,而且,远程仓库的默认名称是origin。
通过例如以下指令,我们能够查看远程分支:
➜ gitTest git:(master) git remote
origin
或者:
➜ gitTest git:(master) git remote -v
origin git@github.com:xuyisheng/testGit.git (fetch)
origin git@github.com:xuyisheng/testGit.git (push)
来显示更具体的信息。
推送分支
要把本地创建的分支同步到远程仓库上,我们能够使用:
➜ gitTest git:(master) git checkout -b dev
Switched to a new branch 'dev'
➜ gitTest git:(dev) git push origin dev
Everything up-to-date
这样就把一个dev分支推送到了远程仓库origin中。
抓取远程分支
当我们将远程仓库clone到本地后即使远程仓库有多个分支,但实际上,本地仅仅有一个分支——master。
➜ MyWork git clone git@github.com:xuyisheng/testGit.git
Cloning into 'testGit'...
remote: Counting objects: 24, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 24 (delta 2), reused 23 (delta 1), pack-reused 0
Receiving objects: 100% (24/24), done.
Resolving deltas: 100% (2/2), done.
Checking connectivity... done
➜ MyWork cd testGit
➜ testGit git:(master) git branch
* master
如今。我要在dev分支上开发。就必须创建远程origin的dev分支到本地,用这个命令创建本地dev分支:
➜ testGit git:(master) git checkout -b dev origin/dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'
➜ testGit git:(dev)
这样就把本地创建的dev分支与远程的dev分支关联了。
后面你能够使用git push origin dev继续提交代码到远程的dev分支。
这样的情况下,假设其它人也提交了到dev分支,那么你的提交就会与他的提交冲突。因此,你须要使用git pull先将远程改动拉取下来。git会自己主动帮你在本地进行merge,假设没有冲突,这时候再提交,就OK了,假设有冲突,那么必须手动解除冲突再提交。
Tag
Tag的概念很相似于branch。可是branch是能够不断改变、merge的。Tag不行,Tag能够觉得是一个快照。用于记录某个commit点的历史快照。
创建标签
很easy:
➜ testGit git:(master) git tag version1
默认Tag会打在最后的提交上。可是你也能够通过commit id来指定要打的地方。
➜ testGit git:(master) git tag version0 b687b06fbb66da68bf8e0616c8049f194f03a062
➜ testGit git:(master) git tag
version0
version1
PS : 实际上commit id不须要写很长,通过前6、7位,git就能够查找到相应的id了。
还能够创建带有说明的标签,用-a指定标签名,-m指定说明文字:
git tag -a v1 -m "version1" b687b06fbb66da68bf8e0616c8049f194f03a062
通过例如以下指令来查看具体信息:
git show <tagname>
查看标签
➜ testGit git:(master) git tag
version1
删除标签
-d參数就能够了,与branch相似。
➜ testGit git:(master) git tag
version0
version1
➜ testGit git:(master) git tag -d version0
Deleted tag 'version0' (was b687b06)
➜ testGit git:(master) git tag
version1
推送到远程
将本地tag推送到远程參考上:
➜ testGit git:(master) git push origin version0
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:xuyisheng/testGit.git
* [new tag] version0 -> version0
或者:
➜ testGit git:(master) git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:xuyisheng/testGit.git
* [new tag] version1 -> version1
来push全部的tag。
删除远程Tag
当Tag已经push到远程仓库后,我们要删除这个Tag。首先须要先删除本地Tag:
➜ testGit git:(master) git tag -d version0
Deleted tag 'version0' (was b687b06)
再push到远程,带指令有所不同:
➜ testGit git:(master) git push origin :refs/tags/version0
To git@github.com:xuyisheng/testGit.git
- [deleted] version0
以上。
学完这些,对付主要的Git使用。就没什么问题了。后面会再出一篇Git workflow plus。介绍一下Git的高级 操作。