# Git标签使用技巧

### 1.远程仓库中拉取指定分支 <a href="#id-1-yuan-cheng-cang-ku-zhong-la-qu-zhi-ding-fen-zhi" id="id-1-yuan-cheng-cang-ku-zhong-la-qu-zhi-ding-fen-zhi"></a>

一定遇到这种情况，github看到一个心仪的开源仓库，但是分支太多，我们只想要我们需要的分支。

```bash
git clone -b <指定分支名> <远程仓库地址>
```

### 2.递归克隆 <a href="#id-2-di-gui-ke-long" id="id-2-di-gui-ke-long"></a>

项目里包含的一些库或者一些模块是存在了别的仓库，可以用递归来克隆回来。一次性就能解决所有的依赖模块

```
git clone --recursive https://github.com/dotnet/aspnetcore.git
```

### 3.切换到指定分支 <a href="#id-3-qie-huan-dao-zhi-ding-fen-zhi" id="id-3-qie-huan-dao-zhi-ding-fen-zhi"></a>

分支众多，要切换到指定分支

```bash
#branch分支管理
git branch
git switch 分支名
```

### 4.创建标签 <a href="#id-4-chuang-jian-biao-qian" id="id-4-chuang-jian-biao-qian"></a>

```bash
git tag v1.0
#默认标签是打在最新提交的commit上
```

### 5.为指定的commit id创建标签 <a href="#id-5-wei-zhi-ding-de-commitid-chuang-jian-biao-qian" id="id-5-wei-zhi-ding-de-commitid-chuang-jian-biao-qian"></a>

上面标签，是为最新的一次提交创建的。但是我们想吃后悔药——为之前的提交创建标签，该怎么做呢！？

```bash
$ git log --pretty=oneline --abbrev-commit
$ git tag 标签值 commitId

#查看标签信息
$ git show 标签值
```

### 6.删除标签 <a href="#id-6-shan-chu-biao-qian" id="id-6-shan-chu-biao-qian"></a>

```bash
$ git tag -d v0.1

#删除远程标签
$ git tag -d v0.9
$ git push origin :refs/tags/v0.9
```

### 7.推送标签至远程仓库 <a href="#id-7-tui-song-biao-qian-zhi-yuan-cheng-cang-ku" id="id-7-tui-song-biao-qian-zhi-yuan-cheng-cang-ku"></a>

```bash
#推送指定标签至远程
$ git push origin v0.1

#推送全部标签至远程
$ git push origin --tags
```

### 8.切换至标签 <a href="#id-8-qie-huan-zhi-biao-qian" id="id-8-qie-huan-zhi-biao-qian"></a>

```bash
#tag标签管理
git tag
#切换
git checkout tag值
```

### 9.本地没有远程标签 <a href="#id-9-ben-di-mei-you-yuan-cheng-biao-qian" id="id-9-ben-di-mei-you-yuan-cheng-biao-qian"></a>

```bash
#查看本地标签
git tag -l

#查看远程标签
git ls-remote -t

#删除本地标签
git tag -d 待删除的标签值

#拉取远程的标签
git fetch origin --prune-tags

#再次查看本地标签
git tag
```

### 10.gitignore文件重新生效 <a href="#id-10gitignore-wen-jian-zhong-xin-sheng-xiao" id="id-10gitignore-wen-jian-zhong-xin-sheng-xiao"></a>

从gitee 创建仓库，可选择创建不同项目下.gitignore文件模板。但是我们修改.gitignore文件，并不生效。.gitignore只能忽略那些原来没有被track的文件，如果某些文件已经被纳入了版本管理中，则修改.gitignore是无效的,把要忽略的文件改为未track状态

```bash
git rm -r --cached .  #清除缓存   取消跟踪所有文件，但不删除本地文件
git add . #重新trace file  
git commit -m "update .gitignore" #提交和注释  
git push origin master #可选，如果需要同步到remote上的话  
```

### 11.本地关联远程 <a href="#id-11-ben-di-guan-lian-yuan-cheng" id="id-11-ben-di-guan-lian-yuan-cheng"></a>

一般情况，常规操作是先在`github`或者`gitee`创建远程仓库，然后

```bash
git clone 
git add -A
git commit -m ""
git push -u origin master
```

但是还有一种情况，先通过`git init`创建的本地仓库，突然发现今天写的代码太优美了，要整个远程仓库存起来。

```bash
#初始化-建立本地仓库
git init

#把本地仓库与远程仓库关联
git remote add origin git@gitee.com:RandyField/xxxxx.git

#push
git push -u origin master

#但是可能会出现如下错误
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@gitee.com:RandyField/xxxxx.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

#原因是创建远程仓库，和本地仓库没有关联，也具有差异

#把远程仓库和本地同步，消除差异，把两段不相干的分支进行强行合并
git pull origin master --allow-unrelated-histories 

git add -A
git commit -m "[dev]init"
git push -u origin master
```

### 12.变基->快进合并 <a href="#id-12-bian-ji-kuai-jin-he-bing" id="id-12-bian-ji-kuai-jin-he-bing"></a>

将提交到某一分支上的所有修改都移至另一分支上，就好像“重新播放”一样(**将一个分支的修改操作在另一个分支最新的提交基础上在依次应用**)。

```bash
#小明童鞋，克隆
git clone xxx.git

#小明童鞋，创建了dev分支
git switch -c dev

git add .
git commit -m "c"

git add xxx.go
git commit -m "update xxx.go"

git add App.vue
git commit -m "update App.vue"

#大明童鞋，克隆
git clone xxx.git
git add main.js
git push -u origin master

#小明童鞋
git switch master
git pull
git switch dev
git rebase master
#有冲突，需要手动合并文件解决，解决冲突后使用git add表示冲突已经解决
git add .
#表示继续下一个冲突
git rebase --continue
#切换至master
git switch master
#快进合并
git merge dev


# 其他命令
git rebase --skip #表示跳过当前冲突，
git rebase --abort #表示退出rebase模式，回到运行git rebase master命令之前的状态

```

`rebase`干了什么？

* 找到`master`和`dev`最近一个共同的父commit对象
* 并找出这个共同的父commit对象到dev分支最新提交对象之间的所有对象，将这些对象依次添加至master分支最新一次提交后。这个过程很像将一个数组追加到另一个数组，没错append操作。
* 这时我们`git rebase master`会提示有冲突(因为我们在master和dev可能修改了相同的文件)，对冲突文件进行手工合共，然后`git add .`标记冲突解决，`git rebase --continue`告诉Git冲突已经解决。
* 在`dev`分支上变基(git rebase master)。这时我们回到msater分支执行 `git merge dev`就可以进行"快进(fast-forward)“模式合并。
