git 配置和查询用户名、邮箱
// 配置用户名和邮箱
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
// 查询用户名和邮箱
git config user.name
git config user.email

git 添加文件到暂存区和仓库
使用命令git add ,注意,可反复多次使用,添加多个文件;
使用命令git commit -m ,完成。
git commit 可以一次添加多个文件。
git add readme.txt
git commit -m "create a readme.txt"
使用git status命令查看当前仓库状态
git status

使用git diff查看修改的内容
git diff顾名思义就是查看difference,显示的格式正是Unix通用的diff格式。-号是git库上版本内容,+号是最新修改后的内容。
git diff readme.txt

使用git add添加到暂存区后,再查询一下整个仓库的状态,发生了变化,提示变化可以被提交。

git commit提交后,再查询一下整个仓库状态,就会显示工作树是干净的。

git查看提交日志
git log,显示从近到远的提交记录。还有可选参数--pretty=onelie,来简略显示提交记录的打印。
git log
git log pretty=oneline


commit 后面跟的一大串数字就是通过算法计算出的一个版本号(commit id),很好的避免了每个人的版本冲突。
git回退到之前的版本
在git中,用HEAD表示当前版本,也就是最新的提价,上一个版本就是HEAD^,上上个版本就是HEAD^^,如果是向前数100个版本,可以简写为HEAD~100。
使用git reset命令回退到之前的版本。--hard参数是回退到上一个版本的已提交状态,--soft会回退到上个版本的未提交状态,git reset --mixed 回退到上个版本未添加状态。
git reset --haed HEAD^

使用git log查看后,最新的一条提交记录已经找不到了。

如果还想回到最新的提交状态,办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到最新的提交commit id,使用git reset命令,就能回到最新的提交状态了。可以看到确实又回到了最新的提交状态了。
在这里,版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。

查询操作日志
Git提供了一个命令git reflog用来记录你的每一次命令,这个命令记录了每一次操作,最开头的十六进制数就是操作执行完的版本号。
git reflog

查询工作区文件与版本库最新版本的区别
git diff HEAD -- readme.txt

撤销修改
撤销本地修改
令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
git checkout -- file命令中的--很重要,没有--,就变成了"切换到另一个分支"的命令。
git checkout -- filename
撤销暂存区修改
如果你的修改已经被提交到暂存区,但是还没有被提交,你想丢弃,使用命令git reset,可以把暂存区的修改回退到工作区。
// 回退暂存区的修改到工作区
git reset HEAD readme.txt
删除文件
方法一:从版本库上删掉该文件,用git rm掉,并且git commit
git rm nouse.txt
git commit -m "xxxxxx"

方法二:先手动删除文件,使用git add命令和git commit也可以起到删除版本库上文件的作用。
git add nouse.txt
git commit -m "xxxxxx"

删错文件
删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本,使用git checkout命令,其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以"一键还原"。
git checkout -- readme.txt

远程仓库
将本地仓库与远程仓库关联
使用git remote命令可以查询到远程仓库的名字,使用git remote add命令把远程仓库和本地仓库关联起来。关联一个远程库时必须给远程库指定一个名字,origin是默认习惯命名;
git remote add origin git@github.com:michaelliao/learngit.git

将本地库上所有内容推送到远程仓库上
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
git push -u origin master

删除本地与远程库的连接
先用git remote -v查看远程库的信息
git remote -v

根据远程库的名字,使用git remote rm origin 删除与远程库的连接。此处的"删除"其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到GitHub,在后台页面找到删除按钮再删除。

克隆远程仓库
比如这里创建了一个新的文件夹叫github_cp,在这个目录下,执行git clone命令,就能把远程仓库clone到这个目录下,克隆的工程保留了原来的目录结构。


分支管理
分支作用就是,你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
创建与合并分支
每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的 ,所以,HEAD指向的就是当前分支。
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。
当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!
不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

创建与切换分支
创建分支命令是git branch,切换分支命令是git checkout
// 创建并切换分支
git checkout -b dev
或使用
// 创建dev 分支
git branch dev
// 切换到dev分支
git checkout dev

使用git branch 查看分支,git branch会列出所有分支,当前分支前面会标一个*号。

合并分支
合并分支使用git merge命令,可以将两个分支合并。
git merge dev

切换回master分支后,执行合并命令。此次合并是Fast-forward信息,Git告诉我们,这次合并是"快进模式",也就是直接把master指向dev的当前提交,所以合并速度非常快。
// 切换到master分支
git checkout master
// 合并分支
git merge dev


删除分支
使用git branch -d dev来删除dev分支
git branch -d dev

切换分支的新命令 git switch
上面git checkout命令可以使用git switch命令来代替。
// 创建并切换到新的分支
git switch -c dev
// 切换到master分支
git switch master

解决冲突
在master分支和feature1分支,对同一文件进行修改,并且都提交到了对应的分支上,使用git merge命令合并分支时,就会报冲突。

冲突内容如下:Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,选择修改,并进行提交。

可以看到已经完成了合并,两个分支指向的提交都是当前这个位置。

图形格式 查看分支合并情况
git log --graph --pretty=oneline --abbrev-commit,vscode有相同的功能。

分支管理策略
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
使用git merge --no-ff,在合并时禁用fast-forward模式,ff就是fast-forward的缩写。
git merge --no-ff -m "使用非fast-forward 模式的缩写" dev

从下图,可以看出来曾经是有合并的。

bug分支
软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
所有未提交的修改,对于所有分支都是可见的,并且这些修改最终会被某次提交所独占。
这里,新创建一个dev分支,在这个分支新增加一个文件。

如果这次的文件不想提交,但是又想切换分支进行别的工作,那么可以使用git stash将当前暂存区储藏起来,等之后再继续工作。
储存工作区 git stash
将暂存区的代提交内容使用git stash,储存起来,用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug,并且支持多次暂存。
git stash

可以看到有两次存储

查看存储的工作内容
用git stash list命令
git stash list

恢复存储的工作区 git stash apply和git stash pop
一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
另一种方式是用git stash pop,恢复的同时把stash内容也删了,在下图可以看到pop的最后也是使用drop来删除stash内容。
使用pop命令恢复现场
git stash pop

使用apply命令恢复现场
// 直接使用功能索引来恢复暂存区现场,两种索引使用方式0或者stash@{1}
git stash apply 0
git stash pop "stash@{1}"


git stash drop删除暂存区的存储
git stash drop "stash@{0}"

git cherry-pick 复制特定的提交到当前分支
git cherry-pick 提交id号

可见确实有特定的提交复制到了当前分支。
强制删除分支
如果分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用大写的-D参数。。
// 强制删除dev分支
git branch -D dev
多人协作
你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
查看远程库信息
首先,可以尝试用git push origin 推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!
// 要查看远程库的信息,用
git remote
// 用git remote -v显示更详细的信息
git remote -v
显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。

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

抓取分支
创建远程origin的dev分支到本地
git checkout -b dev origin/dev

修改传递到指定远程分支
git push origin dev

把远程分支拉取下来
git pull origin dev

Rebase
git rebase
rebase操作可以把本地未push的分叉提交历史整理成直线;
rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
创建和查看标签
在Git中打标签非常简单,使用git tag v1.0命令就能创建。
// 创建标签
git tag v1.0
// 查看标签
git tag

默认标签是打在最新提交的commit上的,但是也可以给历史提交打上标签,找到历史的commit id就可以打上了。
git tag v0.9 0dde9a783237ff33c965184cd687bf8143d8d9a0

再用命令git tag查看标签

查看标签信息
git show v0.9

创建带有说明的标签
git tag -a v0.1 -m "version 0.1 released" c12dcf

标签删除
git tag -d v0.1

推送某个标签到远程
git push origin v1.0

一次性推送全部尚未推送到远程的本地标签
git push origin --tags

删除远程标签
-
先从本地删除
git tag -d v0.9

-
再从远程删除
git push origin :refs/tags/v0.9

检出标签
我们可以根据标签,检出相应版本的代码.
git checkout v1.0
实际使用中,可以先创建新的分支,再检出相应标签的代码,在标签版本的基础上再进行开发。