2021年最新版Git一天入门教程

2023-05-16

0 文章背景

Git在其版本2.23后又引入了git switchgit rerstore,同时Git命令的使用在实际工作过程中不可缺少,因此博主本人自己花了一天时间从头复习并深入了Git的使用过程并撰写了这篇文章,也希望帮助到各位一天掌握Git。
本文主要参考了廖雪峰的Git教程,简化了其中简单的Git命令,同时额外详细描述了git mergegit rebase等重点Git命令的使用方式以及原理。

1 安装Git

如果你正在使用Mac做开发,有两种安装Git的方法。

一是安装homebrew,然后通过homebrew安装Git,具体方法请参考homebrew的文档:http://brew.sh/。

安装完成后,还需要最后一步设置,在命令行输入:

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。

注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

2 创建版本库

创建一个Git仓库的文件夹:

$ mkdir learngit
$ cd learngit
$ pwd
/Users/michael/learngit

初始化Git仓库:

$ git init

把文件添加到版本库:

$ git add readme.txt
$ git commit -m "wrote a readme file"

3 时光机穿梭

$ git status
//git diff将暂存区的版本跟工作区的版本进行对比
$ git diff readme.txt 

git diff跟不同的参数,比较不同的区间的版本。

  1. git diff:是查看working tree与stage的差别的。
  2. git diff --cached:是查看stage与repository的差别的。
  3. git diff HEAD:是查看working tree和repository的差别的。其中:HEAD代表的是最近的一次commit的信息。

3.1 版本回退

$ git add readme.txt
$ git commit -m "append GPL"
$ git log
$ git log --pretty=online

在Git中用HEAD表示当前版本,也就是最新的提交1094adb...,上一个版本就是HEAD,上上一个版本就是HEAD^,上100个版本可以写成HEAD~100。

$ git reset --hard HEAD^
HEAD is now at e475afc add distributed
$ git reset --hard 1094a
$ git reflog

git log查看提交历史,git reflog查看命令历史。

3.2 工作区和暂存区

3.3 管理修改

3.4 撤销修改

操作Git V2.23-Git 2.23+
从unstaged恢复到worktreegit checkout – <file>git restore <file>
从staged恢复到unstagedgit reset – <file>git restore --staged <file>
从staged恢复到worktreegit checkout --HEAD <commit_id>或者git checkout --HEAD <commit_id>git restore --staged --worktree <file>
从当前提交返回到上一个提交git checkout --HEAD <commit_id>或者git checkout --HEAD <commit_id>git checkout --HEAD <commit_id>或者git checkout --HEAD <commit_id>
$ git checkout -- readme.txt
$ git restore readme.txt
$ git restore .
$ git reset HEAD readme.txt
$ git restore --staged readme.txt
$ git restore --staged .

$ git reset HEAD readme.txt是撤销添加到暂存区中对该文件的修改,工作区的修改不会被撤销。而$ git reset --hard HEAD便是撤销所有工作区和暂存区的修改。

3.5 删除文件

$ git rm test.txt

git rm <file>是从工作区中删除<file>文件,并在暂存区中记录该文件已改变(内容改变、文件新建或删除)的动作,即其等价于:

$ rm fileName.txt
$ git add fileName.txt

4 远程仓库

4.1 添加远程库

//关联一个远程库
$ git remote add origin git@github.com:jed/learngit.git
//使用命令第一次推送master分支的所有内容
$ git push -u origin master
//此后,每次本地提交后想提交到远程仓库可使用下面的命令提交最新修改
$ git push origin master

4.2 从远程库克隆

//从远程仓库克隆了一个本地库
$ git clone git@github.com:jed/gitskills.git

Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。

5 分支管理

操作Git V2.23-Git V2.23+
查看所有分支git branchgit branch
创建分支git branch <branch>git branch <branch>
切换分支git checkout <branch>git switch <branch>
新建并切换分支git checkout -b <branch>git switch -c <branch>
切换到commit_idgit checkout <commit_id>git checkout <commit_id>

5.1 创建与合并分支

HEAD指向分支,而master才指向master分支的提交,并且HEAD指向的就是当前分支。

当Git创建新分支时,例如一个dev分支,Git则新建一个指针指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上。

//创建并切换分支
$ git checkout -b dev
switched to a new branch 'dev'
//git checkout -b dev等价于下面的命令
//创建分支
$ git branch dev
//切换分支
$ git checkout dev
Switched to branch 'dev'
//用git branch命令查看当前所有分支
$ git branch
* dev
  master

git branch命令会列出所有分支,当前分支前面会标一个*号,然后,我们就可以在dev分支上正常提交。

$ git add readme.txt
$ git commit -m "branch test"
//把dev分支的工作成果合并到master分支上,且此次合并是快速合并
$ git merge dev
//合并后可删除dev分支
$ git branch -d dev

注意:git merge会把两个分支最新提交以及两者最近的共同祖先进行三方合并,合并的结果是生成一个新的提交。在master分支执行git merge dev命令,与在dev分支执行git merge master命令,这两个命令的执行效果是不相同的。

Git新版本的切换分支命令为git switch:

//撤销修改命令
$ git checkout -- <file>
//新版本撤销修改命令
$ git restore <file>
//创建分支
$ git branch <branch>
//切换分支命令
$ git checkout <branch>
//新版本切换分支命令
$ git switch <branch>
//创建并切换分支
$ git checkout -b <branch>
//新版本创建并切换分支命令
$ git switch -c <branch>

5.2 解决冲突

准备新分支feature1,继续新分支的开发:

$ git switch -c feature1
Switched to a new branch `feature1`
$ 修改feature1分支此时的工作区文件readme.txt
//在feature1分支上提交:
$ git add readme.txt
$ git commit  -m "and simple"
//切换到master分支
$ git switch master
$ 修改master分支此时的工作区文件readme.txt
//在master分支上提交:
$ git add readme.txt
$ git commit -m "& simple"

这种情况下Git无法执行快速合并,只能试图把各自的修改合并起来,但这种合并可能会有冲突,我们试试看:

$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

果然冲突了!Git告诉我们,readme.txt文件存在冲突,必须手动解决冲突后再提交。git status也可以告诉我们冲突的文件:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

我们可以直接查看readme.txt的内容:

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 of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1

Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,我们修改如下后保存:

Creating a new branch is quick and simple.

再提交:

$ git add readme.txt 
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed

用带参数的git log也可以看到分支的合并情况:

$ git log --graph --pretty=oneline --abbrev-commit
*   cf810e4 (HEAD -> master) conflict fixed
|\  
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/  
* b17d20e branch test
* d46f35e (origin/master) remove test.txt
* b84166e add test.txt
* 519219b git tracks changes
* e43a48b understand how stage works
* 1094adb append GPL
* e475afc add distributed
* eaadf4e wrote a readme file

最后,删除feature1分支:

$ git branch -d feature1
Deleted branch feature1 (was 14096d0).

工作完成。

5.3 分支管理策略

合并分支时,Git会尽可能用Fast Forward模式,但这种模式下,删除分支后会丢失分支信息,如果要强制禁用Fast Forward模式,Git就会merge时生成一个新的commit,这样从分支历史就可以看出分支信息。。,下面来实战一下==no-ff方式的git merge

//首先创建并切换dev分支
$ git switch -c dev
$ 修改readme.txt文件,并提交一个新的commit
$ git add .
$ git commit -m "add merge"
//切换回master
$ git switch master
//禁用快速合并模式的合并,本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去
$ git merge --no-ff -m "merge with no-ff" dev
//合并后用git log查看分支历史:
$ git log --graph --pretty=oneline --abbrev-commit
*   e1e9c68 (HEAD -> master) merge with no-ff
|\  
| * f52c633 (dev) add merge
|/  
*   cf810e4 conflict fixed
...

–no–ff 模式其实就是相当于master指针new了一个跟dev指针一样的空间并且放了相同的内容然后指向这个空间。而原来的快速模式,就是简单将master指针指向dev指针指向的内容而已,并没有自己创造空间。

5.4 Bug分支

在Git中每个Bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

当你接到一个修复一个代号101的Bug的任务时,可以创建一个分支issue-101来修复它,但是如果当前正在dev分支上进行的工作还未提交,因为工作只做到一半无法提交则可以用git stash命令将当前工作现场储藏起来,等以后恢复现场后继续工作:

$ git bash
Saved working directory and index state WIP on dev: f52c633 add merge

git stash不能将未被追踪的文件(untracked file)压栈,也就是从未被git add过的文件,也就是你在使用git status命令看到的提示Untracked files所列出的文件,所以在git stash之前一定要用git status确认没有Untracked files

现在,用git status查看工作区,就是干净的(除非有未被Git管理的文件),因此可放心创建分支来修复Bug。

先确定在哪个分支修复Bug,加入需要在master分支上修复,就从master创建临时分支:

$ git checkout master
//创建并切换到issue-101分支
$ git switch -c issue-101
$ 修复Bug涉及的文件
$ git add .
$ git commit -m "修复Bug-101"
$ git merge --no-ff -m "合并Bug-101" issue-101
//修复完Bug,切换回dev分支工作
$ git switch dev
Switched to branch 'dev'
$ git status
On branch dev
nothing to commit, working tree clean
//工作区是干净的,用`git stash list`命令查看:
$ git stash list
stach@{0}: WIP on dev: f52c633 and merge

我们发现用git stash存储的工作现场还存在,如果想要恢复有两个方法:

  1. git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除。
  2. git stash pop恢复工作现场的同时把stash内容也删了。
$ git stash pop
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   hello.py

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

Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)

再用git stash list查看,就看不到任何stash内容了。

可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:

$ git stash apply stash@{0}

在master分支上修复bug后,仔细一想dev分支是早期从master分支分出来的,所以这个bug其实在当前dev分支上也存在。

要想修复dev分支上同样的Bug,我们只要把4c805e2 fix bug 101这个提交所做的修改“复制”到dev分支。注意:我们只想复制4c805e2 fix bug 101这个提交所做的修改,并不是把整个master分支merge过来。为了方便操作,Git专门提供了一个git cherry-pick命令,让我们能复制一个特定的提交到当前分支:

$ git branch
* dev
  master
$ git cherry-pick 4c805e2
[master 1d4b803] fix bug 101
 1 file changed, 1 insertion(+), 1 deletion(-)

Git自动给dev分支做了一次提交,注意这次提交的commit是1d4b803,它并不同于master和issue-101合并后的提交4c805e2,因为这两个commit只是改动内容相同,但确实是两个不同的commit。用git cherry-pick,我们就不需要在dev分支上手动再把修bug的过程重复一遍。

git cherry-pick <commitHash>将指定的提交应用于当前分支,它也会跟git merge一样产生冲突,其解决冲突的方法跟git merge解决冲突的方法一样:想在文件中解决冲突,再用 git add <fileName>对修正后的文件做标记,然后用 ‘git commit’ 将修改动作提交到本地仓库。

5.5 Feature分支

添加一个新功能时,肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。

接到了一个新任务,即开发代号为Vulcan的新功能:

$ git switch -c frature-vulcan
//开发完毕后
$ git add .
$ git commit -m "add feature vulcan"

但是现在这个需求废弃了,需要删除掉:

//在vulcan分支中删除vulcan分支
$ git branch -d vulcan
error: 无法删除检出于 '/Users/didi/AndroidStudioProjects/MyDemo' 的分支 'vulcan'。
//切换分支到master中
$ git switch master
//在master分支中删除vulcan分支
$ git branch -d vulcan
error: 分支 'vulcan' 没有完全合并。
如果您确认要删除它,执行 'git branch -D vulcan'
$ git branch -D vulcan
已删除分支 vulcan(曾为 58bd560)。

5.6 多人协作

当从远程仓库克隆时,实际上Git自动建立本地仓库master分支与远程仓库master分支的跟踪,并且远程仓库的默认名称是origin。

要查看远程仓库的信息用命令git remote

$ git remote
origin

其中用git remote -v显示更详细的信息:

$ git remote -v
origin  git@github.com:michaelliao/learngit.git (fetch)
origin  git@github.com:michaelliao/learngit.git (push)

上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。

5.6.1 推送分支

推送分支就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样Git就会把该分支推送到远程库对应的远程分支上:

//下述命令的origin是指远程仓库,master是要推送的本地分支,因为如果本地仓库master分支与远程仓库master分支建立了跟踪,那他两分支名都一样的,所以这行命令中只指定了本地分支的名字,而没有指定远程分支的名字
$ git push origin master
//如果想要推送其他本地分支,甚至该分支并不存在于远程仓库,例如dev
$ git push origin dev

git push --set-upstream origin featured等价于git push origin featured吗?

并不是一定要把本地分支往远程推送,那么哪些分支需要推送,而哪些分支不需要推送呢:

  1. master分支是主分支,因此要时刻与远程同步。
  2. dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步。
  3. bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周修复了几个bug。
  4. feature分支是否推送到远程仓库,取决于是否与其他团队成员合作开发。

5.6.2 抓取分支

多人协作时,大家都会往master和dev分支上推送各自的修改。

现在模拟一个团队成员在另一个目录下克隆该项目:

$ git clone git@github.com:jed/learngit.git

当从远程仓库克隆项目后,默认情况下该团队成员只能看到本地的master分支:

$ git branch
* master

现在,该团队成员要在dev分支开发, 则要建立远程仓库的dev分支与本地仓库dev分支的跟踪关系:

git checkout -b dev origin/dev

现在,该团队成员可以在dev分支上继续修改,然后时不时把dev分支推送到远程仓库:

$ 修改env.txt文件
$ git add env.txt
$ git commit -m "add env"
$ git push origin dev
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:jed/learngit.git
   f52c633..7a5e5dd  dev -> dev

而我同时在dev分支上对同一文件的同一处代码进行了修改,再试图推送到远程仓库:

$ 修改env.txt文件
$ git add env.txt
$ git commit -m "add env"
$ git push origin dev
To github.com:jed/learngit.git
 ! [rejected]        dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@github.com:jed/learngit.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/dev抓下来,然后在本地合并解决冲突再推送:

$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> dev

git pull也失败了,因为没有指定本地dev分支与远程origin/dev分支的链接,根据提示设置dev和origin/dev的链接:

$ git branch --set-upstream-to=origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

再pull:

$ git pull
Auto-merging env.txt
CONFLICT (add/add): Merge conflict in env.txt
Automatic merge failed; fix conflicts and then commit the result.

这回git pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突方法完全一样。解决后则commit提交再push推送即可:

$ git commit -m "fix env conflict"
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 621 bytes | 621.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:jed/learngit.git
   7a5e5dd..57c53ab  dev -> dev

5.6.3 多人协作的工作模式总结

因此,多人协作的工作模式通常是这样:

  1. 首先,可以试图用git push origin <branch-name>推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!

如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

5.7 Rebase

5.7.1 git rebase原理

$ git rebase <topic-branch>

git rebase的原理是首先找到这两个分支(即当前分支experiment、变基操作的目标基底分支master)的最近共同祖先提交,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底分支master最新提交,最后以此将之前另存为临时文件的修改依序应用。

git rebase完成后可以切换到master分支进行一次快进合并,而这种合并方式与git merge没有任何区别,但是变基使得提交历史更加整洁。

一般我们这样做的目的是为了确保在向远程分支推送时能保持提交历史的整洁——例如向某个其他人维护的项目贡献代码时。 在这种情况下,你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到 origin/master 上,然后再向主项目提交修改。 这样的话,该项目的维护者就不再需要进行整合工作,只需要快进合并便可。

5.7.2 git rebase实例

假设现在基于远程仓库origin的origin分支,该分支已有C1、C2两个提交,接着创建了一个叫mywork的分支:

$ git checkout -b mywork origin

现在另一个团队成员在origin分支上做一些修改,生成两个commit提交,即C3和C4:

$ vi file.txt
$ git add .
$ git commit -m "第一次commit"
$ vi file2.txt
$ git add .
$ git commit -m "第二次commit"

与此同时,我们在mywork分支做一些修改,生成两个commit提交,即C5和C6:

$ vi file.txt
$ git add .
$ git commit -m "第一次commit"
$ vi file2.txt
$ git add .
$ git commit -m "第二次commit"

此时,我们可在mywork分支使用git pull命令把origin分支上的修改拉下来并且跟我们的修改合并,最后生成一个新的提交C7。

但是,如果我们想让mywork分支历史看起来像没有经过任何合并一样,也可以用git rebase

$ git checkout mywork
$ git rebase origin

这些命令会把你的mywork分支里的每个提交取消掉,并且把他们临时保存为补丁(这些补丁放到.git/rebase目录中),然后把mywork分支更新到最新的origin分支,最后把保存的这些补丁应用到mywork分支上。

当补丁被应用后,mywork分支的HEAD指针会指向新创建的提交C5’和C6’,而那些老的提交(C5和C6)会被丢弃。如果运行垃圾收集命令(pruning garbage collection),这些丢弃的提价就会删除。

img

在rebase过程中也许会出现冲突,Git则会停止rebase并让我们去解决冲突,解决冲突后用git add命令去更新这些内容的索引,然后无需执行git commit(在git rebase时git commit不等价于git rebase --continue),只需执行git rebase --continue,这样git会继续rebase,根据要rebase的提交次数,git rebase --continue要执行相同的rebase的提交次数。

任何时候可以用git reabse --abort 终止rebase操作,并且mywork分支会回到rebase开始前的状态。

如果想让master分支跟进到dev分支最新的提交,可直接使用git merge命令快速模式合并,即让master分支的HEAD指针直接指向dev分支最新的提交。

5.7.3 git rebase风险

git rebase要遵循一条准则:

如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。

变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。如果你已经将体积哦啊推送到远程仓库,而且他人也已经从该仓库拉取提交并进行了后续工作,此时如果你用git rebase命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下你还要拉取并整合他们修改过的提交,情况会变得很糟糕。

6 标签管理

发布一个版本时,我们通常现在版本库中打一个标签Tag,这样就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。

6.1 创建标签

在Git中打标签非常简单,首先切换到要打标签的分支上:

$ git bash
* dev
  master
$ git checkout master
Switched to branch 'master'

然后,敲命令git tag <name>就可以打一个新标签:

$ git tag V1.0

可以用git tag命令查看所有标签:

$ git tag
V1.0

默认标签是搭载最新提交的commit上,有时候忘了给旧的提交打标签,则可以通过找到历史提交的commit_id,再打上就可以了:

$ git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file

比如说要对add merge这次提交打标签,它对应的commit_id是f52c633,敲入命令:

$ git tag V0.9 f52c633

再用命令git tag查看标签:

$ git tag
v0.9
v1.0

注意,标签不是按时间顺序列出,而是按字母排序的,可以用git show <tagname>查看标签信息:

$ git show v0.9
commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:56:54 2018 +0800

    add merge

diff --git a/readme.txt b/readme.txt
...

可以看到,v0.9确实打在add merge这次提交上,还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

$ git tag -a v0.1 -m "version 0.1 released" 1094adb

用命令git show <tagname>可以看到说明文字:

$ git show v0.1
tag v0.1
Tagger: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 22:48:43 2018 +0800

version 0.1 released

commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (tag: v0.1)
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:06:15 2018 +0800

    append GPL

diff --git a/readme.txt b/readme.txt
...

注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。

6.2 操作标签

如果标签打错了,也可以删除:

$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)

因为创建的标签斗志存储在本地,不会自动推送到远程仓库,所以,打错的标签可以在本地安全删除。

如果想要推送某个标签到远程仓库,使用命令git push origin <tagname>

$ git push origin v1.0

或者,一次性推送全部尚未推送到远程的本地标签:

$ git push origin --tags

如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

$ git tag -d 0.9

然后从远程仓库删除,删除命令也是push,但是格式如下:

$ git push origin :refs/tags/v0.9

要看看是否真的从远程库删除了标签,可以登陆GitHub查看。

本文参考文献:

Git教程

Git新命令switch和restore

3.6 Git 分支 - 变基

git rebase命令

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2021年最新版Git一天入门教程 的相关文章

  • java使用线程池和Future接口实现异步的实例

    线程池可以提供线程的复用和管理 xff0c 避免线程频繁创建和销毁的开销 而Future接口则可以获取异步任务的执行结果和状态 xff0c 避免了阻塞等待异步任务完成的情况 下面是一个简单的示例代码 xff1a 96 96 96 impor
  • 我程序人生的启蒙书

    是这本书 xff0c 大一的我接触了c和c 43 43 xff0c 为数学专业的我打开了通往另一个世界的道路 xff0c 做一名优秀的程序员 是这本书 xff0c 大一的我开始废寝忘食的学习 xff0c 自习室里往往就放着这一本数 xff0
  • Leetcode Decode Ways 解题报告

    A message containing letters from A Z is being encoded to numbers using the following mapping 39 A 39 gt 1 39 B 39 gt 2
  • 研究生计算机专业的方向有哪些?

    链接 xff1a https www zhihu com question 349899328 answer 1752872326 编辑 xff1a 深度学习与计算机视觉 声明 xff1a 仅做学术分享 xff0c 侵删 作者 xff1a
  • Android Studio使用OpenCV进行图像基本处理

    Android Studio使用OpenCV进行图像基本处理 1 环境配置 进入OpenCV官网下载SDK包 进入官网 xff08 https opencv org releases xff09 选择 34 Android 34 版本下载
  • QT中基于QWebEngineView的C++和JS互相调用

    QT版本5 14 2 xff0c ubuntu18 04 4 1 PRO包含库 QT 43 61 webenginewidgets 2 main中启用OpenGL QCoreApplication setAttribute Qt AA Us
  • cin相关函数

    cin cin的相关函数 get getline gt gt ignore cin cout 都关联一个行缓冲区 按下enter键 xff0c 生成一个 n 在缓冲区中 xff0c 同时也就可以操作这一行了 cin get 从缓冲区取一个字
  • 浅谈人工智能(AI)

    人工智能 AI 一 人工智能简介 1 1 人工智能定义和发展历史 人工智能 xff08 Artificial Intelligence xff09 xff0c 英文缩写为AI 它是研究 开发用于模拟 延伸和扩展人的智能的理论 方法 技术及应
  • ubuntu18.04忘记密码的解决办法

    大半年没动的U盘系统忘了用户登录密码 xff0c root密码也忘记 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 简单记录一下 xff0c
  • iocp 非阻塞Socket异步接收限速

    网上找遍了也没找到关于异步非阻塞Socket的限速资料 于是 自己写了一份 限速100M S 误差15M S 限速50M S 误差5M S 限速10M S 误差0 3M S 限速5M S 误差0 02M S 限速越小 精度越准 functi
  • qt发布的程序时如何将依赖的dll分开放在不同目录下

    qt发布的程序时如何将依赖的dll分开放在不同目录下 QT发布的程序 xff0c exe可执行程序与dll文件都在同一个目录下 xff0c 我现在想把那些dll文件 xff0c 放到一个文件夹下 xff0c 这个文件夹和exe在同一个目录下
  • Android性能优化:Bitmap详解&你的Bitmap占多大内存?

    在开发app时 xff0c 显示一张本地图片 xff0c 这张图片在加载时会占用大多内存呢 xff1f 猜测占用内存大小和以下几个因素有关 xff1a 设计师切图 xff0c 图片本身的分辨率 xff1b 图片所放文件夹代表的 密度 dpi
  • HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

    HashMap的初始容量都是2的n次幂的形式存在的 xff0c 而扩容也是2倍的原来的容量进行扩容 xff0c 也就是扩容后的容量也是2的n次幂的形式存在的 xff0c 下面就来说明一下为什么是2的n次幂的形式 xff01 先来看一下源码
  • ARM裸机第五部分-SDRAM和重定位relocate

    第一部分 章节目录 1 5 1 汇编写启动代码之关看门狗 1 5 2 汇编写启动代码之设置栈和调用C语言1 1 5 3 汇编写启动代码之设置栈和调用C语言2 1 5 4 汇编写启动代码之开iCache 1 5 5 重定位引入和链接脚本1 1
  • Java线程死锁的原因和条件

    一 死锁概念 所谓死锁 xff0c 是指多个进程在运行过程中因争夺资源而照成的一种僵局 当进程处于这种僵持状态时 xff0c 若无外力作用 xff0c 它们都将无法再向前推进 二 产生死锁的原因 xff08 1 xff09 竞争资源 当系统
  • Ubuntu 14.04无法连接ssh服务解决方法

    解决方法如下 xff1a 1 先试着开启SSH服务 在使用SSH之前 xff0c 可以先检查SSH服务有没有开启 使用命令 xff1a sudo ps e grep ssh 来查看 xff0c 如果返回的结果是 xxxx 00 00 00
  • 1.14.ARM裸机第十四部分-LCD显示器

    第一部分 章节目录 1 14 1 LCD简介 1 14 2 LCD的接口技术 1 14 3 LCD如何显示图像1 1 14 4 LCD如何显示图像2 1 14 5 LCD的六个主要时序参数1 1 14 6 LCD的六个主要时序参数2 1 1
  • LCD常用接口原理

    LCD常用接口原理 点击打开链接 点击打开链接 点击打开链接 点击打开链接 点击打开链接 点击打开链接 点击打开链接 点击打开链接 xubin 平台信息 内核 xff1a linux2 6 linux3 0 系统 xff1a android
  • 1.15.ARM裸机第十五部分-触摸屏TouchScreen

    第一部分 章节目录 1 15 1 输入类设备简介 1 15 2 电阻式触摸屏的原理 1 15 3 S5PV210的电阻触摸屏控制器 1 15 4 电容触摸屏的原理 1 15 5 ft5x06电容触摸IC简介 第二部分 章节介绍 1 15 1
  • MAC【Android studio】Gradle download:kotlin-compiler-embeddable-1.3.70.jar下载太慢

    采用策略去Maven仓库下载资源 更新到本地进行加载 1 进入仓库网址链接 https mvnrepository com 点击下载如图 2 配置下载jar文件到 gradle文件中 文件路径 Users 34 用户名 34 gradle

随机推荐

  • 线程安全是如何实现的?

    实现线程安全与代码编写有很大的关系 xff0c 但虚拟机提供的同步和锁机制也起到了至关重要的作用 互斥同步 互斥同步 xff08 Mutual Exclusion amp Synchronized xff09 是一种最常见也是最主要的并发正
  • 2022,音乐号自媒体起号涨粉保姆级攻略,这是个收获的季节。

    前言 最近遇到好多朋友说想做短视频自媒体 xff0c 但找了很多资料 xff0c 甚至报了学习班也没什么起色 xff0c 这不前天一个姐姐说他家姑娘想做抖音 xff0c 俩月了没啥粉丝也没啥播放量 xff0c 看到我的音乐号了 xff0c
  • 短视频消重去重九种方法,组合使用原创度更高,各平台轻松过原创

    想做好视频去重 xff0c 首先要了解视频查重的机制 网上流传的检查MD5其实已经过时了 xff0c 现在MD5已经是过去式 查重要对视频的方方面面进行检查 xff0c 包括但不限于 xff1a 视频的标题 xff0c 封面 xff0c 描
  • 不直播不露脸也能做短视频变现,想挣点生活费试试这些玩法

    大家好 xff0c 我是 64 我赢助手短视频运营 xff0c 最近一直有小伙伴问我 xff0c 做了好久的短视频一直不赚钱 xff0c 今天总结了一下 xff0c 做了90天短视频还没赚了试试这5种易变现的玩法 新手不直播不露脸也能做短视
  • 科普一下:拍抖音需要什么设备,可能用到的设备合集

    大家好 xff0c 我是 64 我赢助手短视频运营 xff0c 抖音是现在最火的短视频平台之一 xff0c 几乎每个人都在用它 xff0c 抖音视频的发展离不开手机 但你知道吗 xff1f 手机拍摄有很多方面的限制 xff0c 比如手持稳定
  • 短视频上热门技巧总结,这样做你也可以快速上热门。

    最近开始做短视频 xff0c 找了很多短视频运营创作技巧 xff0c 但能上热门的只有那么几个 xff0c 经过近一周的分析 xff0c 结合了我赢上短视频运营创作技巧 xff0c 得到了以下几个经典技巧合集 xff1a 学会一个就值了 首
  • 不要再被骗了,解密短视频里追剧看电影都能赚钱的坑。

    不要再被骗了 解密短视频里追剧看电影都能赚钱的坑 最近刷短视频刷到了好多抖音追剧看电影每天收几百 xff0c 还有截图 xff0c 还有怎么实操的视频 关键不是刷到一个两个 xff0c 是几十个还有越来越多的趋势 都说新入门实操 xff0c
  • 视频号的视频怎么下载到手机?不录屏也不找手机缓存,一键下载。

    你有没有看到有用的视频 xff0c 只收藏起来 xff0c 最后又找不到的时候 前天给朋友找了一个过年快速整理家具杂物的教程 xff0c 谁知道原作者第二天把视频给删掉了 xff0c 朋友说没有来得及看 昨天发给了朋友一个最新的教程 xff
  • 2023年做好自媒体的五个步骤,一步一个脚印稳妥找到结果。

    2023年做好自媒体的五个步骤 一步一个脚印稳妥找到结果 我不管你现在什么负债 破产 xff0c 还是迷茫焦虑 xff0c 通通别管了 xff0c 听话照做执行 看完我这篇内容 xff0c 2023年你还做不起来 xff0c 你就别打嘴炮
  • 2023视频号视频怎么下载到手机?最新验证过的可用方法汇总

    视频号视频怎么下载到手机 xff1f 今天又想下载一个视频号的视频 xff0c 找到收藏已久的视频号视频下载方法 xff0c 结果发现很多方法已经不能用 xff0c 一些能用的也开始收费了 只好重新寻找适合2023最新的几种方法解决视频号下
  • Android系统签名制作

    系统环境 Ubuntu18 04 首先要有对应系统的源码 源码目录build target product security将platform pk8和platform x509 pem copy出来放到一个目录下生成shared priv
  • 使用Cropper进行图片剪裁上传

    在项目中 xff0c 需要多上传的图片按照比例和尺寸进行裁剪 xff0c 这类场景在一些CMS系统中是比较常见的 xff0c 尤其是大部分的文章现在要适配PC Mobile两种平台 xff0c 文章的封面图等便需要按照尺寸做裁剪 xff0c
  • Element-UI消息提示组件Message在Vuex中的调用实现

    在最近的项目开发中 xff0c 前端部分使用 Vue 开发 xff0c 整个页面基于 Element UI 实现 由于是单页面多组件应用 xff0c 使用了 Vuex 做状态管理 为了页面交互的友好和风格的统一 xff0c 消息提醒使用 E
  • Fork原项目新增分支的同步和推送

    在 Github 或者 Gitlab Fork 项目以后 xff0c 原项目增加了新的分支 xff0c 我们可以通过以下流程将分支同步下来 本项目前提假设我们设置了 remote 的名称为 up 与源项目关联 git remote v or
  • Elasticsearch文档版本冲突原理与解决

    一般我们在更新文档时 xff0c 主要的操作流程时 xff1a 读取文档 gt 修改 gt 提交保存 数据中心等保存的都是最新一次提交的内容 大部分时候 xff0c 这都没有什么问题 但是如果两个或更多的请求同时修改一个文档时 xff0c
  • 随笔

    沟通 跨部门沟通 xff0c 首先应确立沟通的目的是双方的有效配合和问题解决的方向 方法 xff0c 去除程序员们自带的问题责任论 xff0c 不能按照 不是我的问题 xff0c 我这OK xff0c 跟我无关 这样的思路去讨论和解决问题
  • Linux内存消耗

    原文 xff1a https web archive org web 20120520221529 http emilics com blog article mconsumption html 本文主要描述如何通过一个合理的方法来测量li
  • ubuntu22 允许root权限远程登录设置

    在 etc ssh sshd config文件中设置 注释 PermitRootLogin prohibit password 添加PermitRootLogin yes
  • 2021年完美解决Gradle下载慢的问题(Android Studio)

    1 问题背景 安卓开发过程中 xff0c 经常会遇到Gradle Wrapper包下载缓慢导致项目无法编译影响开发效率问题 xff0c 极端情况下下载速度只有10kb xff0c 下载一个特定版本的Gradle需要半个小时以上 xff0c
  • 2021年最新版Git一天入门教程

    0 文章背景 Git在其版本2 23后又引入了git switch和git rerstore xff0c 同时Git命令的使用在实际工作过程中不可缺少 xff0c 因此博主本人自己花了一天时间从头复习并深入了Git的使用过程并撰写了这篇文章