GIT速查手册

一、GIT

1.1 简单配置

git是版本控制系统,与svn不同的是git是分布式,svn是集中式

配置文件位置

# 配置文件
.git/config 当前仓库的配置文件
~/.gitconfig 全局配置文件

# 查看所有配置项
git config --list

友好的查看日志

# 设置别名
# 友好的查看日志
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 --all"

git log --decorate --oneline --graph --all
git lg

设置用户名和邮箱

# 设置用户名和邮箱
git config --global user.name "xxx"
git config --blobal user.email "xxx@xxx.com"

1.2 工作区和暂存区

工作区(Working Directory)是当前文件夹,当前文件夹下的.git文件夹是版本库(Repository)。版本库里有很多东西,其中有

  1. 最重要的就是暂存区(stage或index)
  2. Git为我们自动创建的第一个分支master
  3. 指向master的一个指针叫HEAD

工作区--暂存区(stage/index)--当前分支(master)--远程库

关系图

版本说明

HEAD 当前版本
HEAD^ 上一版本
HEAD^^ 上上版本
HEAD~100 往上100个版本

1.3 add/commit/diff/reset

add命令

commit命令

diff命令

reset

二、常用命令

2.1 init/add/commit/status/log

init

cd learngit
git init

# 在某目录下执行命令后,该目录会生成一个.git的隐藏文件夹,这个目录就是一个版本库了
# 所有版本控制系统只能跟踪文本文件的发动
# 如TXT文件中删除了第4行,图片等二进制文件作为一个整体
# 统一用UTF-8编码

add

# 添加一个文件到暂存区(Stage)
vi readme.txt
git add readme.txt

commit

# 将文件提交给HEAD
git commit -m 'wrote a readme file'

# 不产生新快照的提交
git commit --amend  

查看状态

git status
# 通过该命令可以清楚的了解当前版本库中的文件处于什么状态

查看历史

git log
git log --pretty=oneline
git lg
# 自定义的一个别名,参照 简单设置

git reflog
# 查看执行的每一条命令

2.2 文件对比

准备

# 工作区的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.
# 暂存区的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 by stage.
# master的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.

比较工作区与暂存区中的文件

git diff -- readme.txt

比较工作区与版本库中的文件

git diff HEAD -- readme.txt

比较暂存区与版本库

git diff --cached HEAD

比较两个历史快照

git diff id1 id2

2.3 版本回退

有如下几个版本:

查看历史记录是这样的:

回退到指定版本:

git reset HEAD^/comment_id
# comment_id,ID号,前7位,可以通过git reflog和git log命令进行查看 

版本库覆盖xxx

# 工作区----暂存区(stage)----版本库(HEAD)----服务器
# 三种模式soft/mixed/hard,默认是mixed

# 版本库里上一版本覆盖最新版本
git reset --soft HEAD^
# 1.移动HEAD的指向,将其指向上一个快照

# 版本库上一版本覆盖最新版本和暂存区
git reset --mixed HEAD^
# 1.移动HEAD的指向,将其指向上一个快照
# 2.将HEAD移动后指向的快照回滚到暂存区域

# 版本库上一版本覆盖最新版本和暂存区和工作区
git reset --hard HEAD^
# 1.移动HEAD的指向,将其指向上一个快照
# 2.将HEAD移动后指向的快照回滚到暂存区域
# 3.将暂存区域的文件还原到工作目录

暂存区覆盖工作区

# 暂存区的内容覆盖工作区(丢弃工作区的修改)
# 撤销工作区的修改
# 没有--,该命令就是切换分支的命令了
git checkout -- readme.txt

版本库覆盖暂存区

# 版本库的内容覆盖暂存区(丢弃暂存区的修改)
# 撤销暂存区的修改
git reset HEAD readme.txt

2.4 暂存区修改

这样一种场景:工作区,暂存区,版本库里内容一样,类似.project类似这种eclipse的项目配置文件也存在于版本控制中,现在把.project这类文件加入到忽略名单后

# 这个命令是把.project从暂存区中删除
git rm --cached .project
# 提交暂存区
git commit -m "delete .project"

2.5 删除/重命名

# 只能删除工作区和暂存区中的文件
git rm filename

# git rm readme.txt与如下两个命令等价
rm readme.txt
git add readme.txt

# 如果工作区和暂存区中的文件内容不同时,下面两个命令可把两个都删除
git rm -f filename
git rm --cached filename

# 重命名
git mv filename1 filename2

三、远程仓库

3.1 免登录设置

Windows下生成ssh-keygen

1.安装Git
2.打开Git Bash
3.输入 ssh-keygen -t rsa -C "your email"

Linux下生成ssh-key

ssh-keygen -t rsa -C "your email"
cat ~/.ssh/id_rsa.pub
# ~/.ssh/id_rsa  这是私钥
# ~/.ssh/id_rea.pub  这是公钥

# 验证
ssh -T git@git.oschina.net

3.2 远程库命令

关联远程仓库

# 把本地仓库与远程仓库相关联
git remote add origin git@github.com:yysue/learngit.git
# yysue:github账户名或gitee账户名
# origin:远程库的名字,这是Git默认的叫法

# 关联分支
git branch --set-upstream-to=origin/master master
# 将本地的master分支与远程origin库的master分支关联

# pull,第一次pull加--allow-unrelated-histories
# https://stackoverflow.com/questions/37937984/git-refusing-to-merge-unrelated-histories-on-rebase
git pull --allow-unrelated-histories

直接修改配置

# 当前版本库目录下
$ cat .git/config
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
[remote "origin"]
        url = git@git.oschina.net:yysue/mysqldba.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master

查看远程库

git remote -v

推送到远程库

git push -u origin master
# 把本地所有内容推送到远程库上
# -u参数,不但会把本地master分支推送到远程master分支,还会把本地master分支与远程master分支相关联
# 第一次推送用-u,以后用就可以不用了
git push origin master

从远程库抓取

git pull origin master

从远程库克隆

git clone git@github.com:h2o1k/gitskills.git        ssh协议,速度快
git clone https://github.com/h2o1k/gitskills.git    https协议

远程仓库强制覆盖本地文件

git fetch --all  
git reset --hard origin/master 
git pull

四、分支管理

4.1 branch/checkout/merge

查看master分支

master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点

创建并切换到dev分支

# 查看当前分支的命令
git branch

git checkout -b dev
# -b 表示创建并切换,与下面两条命令等价
git branch dev
git checkout dev

# 再查看一下分支
git branch

在dev分支提交

vi dev.txt
Creating a new branch is quick.

git add dev.txt
git commit -m "add dev.txt"

切换到master分支

git checkout master

dev合并到master

git merge dev -m "merge dev"
# merge合并指定分支到当前分支,
# so,必须在master分支下执行上述命令

保留分支信息的合并

git merge --no-ff -m "merge" dev
# --no-ff会保留分支信息

通常,分支合并时,Git会用Fast forward模式,这种模式下,删除分支后,会丢失分支信息,禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息

删除dev分支

git branch -d dev

产生冲突

master分支和feature1都有新的提交

解决冲突

编辑冲突文件,然后再添加、提交、合并,最后删除分支feature1

查看日志

分支管理策略

4.2 stash

我们有时会遇到这样的情况,正在分支a上开发一半,然后分支b上发现Bug,需要马上处理。

这时候分支a上的修改怎么办呢,git add 是不行的,有的git客户端版本会提示还有add过的文件没提交不能切换分支,有的git客户端版本会把修改带到b分支。

git stash 就是解决这个问题,它把当前工作区的修改和git add的内容都保存到一个地方,然后git reset HEAD,使工作区回到上一次提交,处于干净状态。然后就可以很放心的切到另外的分支b干活了。

git stash save “先给我保存一下,我要去别的分支修bug”
git stash list
# 切换到其他分支去修改bug
# ...
# 再切换到打stash的分支
git stash pop
# git stash pop相当于执行git stash apply和git stash drop
git stash apply stash@{num}

4.3 rebase

有的时候我们在一个分支a开发的时候,master已经进入了很多修改,这时候如果把a的修改提交上去,可能就会跟主干有冲突,需要在主干解决冲突才能提交,这样比较难看。

这时候git rebase就有用了,git rebase BRANCH_NAME可以把BRANCH_NAME分支的修改带到当前分支来,这样当前分支就有了BRANCH_NAME分支的所有内容,这样在当前分支开发的内容提交以后不会跟BRANCH_NAME有冲突,冲突在当前分支就可以解决。

4.4 小技巧

可以取消已经提交的commit,一般我们只用git reset HEAD^。因为每个分支可能开发过程中为了保存过程以便回溯会有很多commit,但是我们要求进入主干时,每个功能和bugfix只能有一个提交,因此可以先用git reset退回到最早的commit,然后把自己的修改最后打包成一个commit,再去跟主干合并。

利用这两个命令,我们可以很好的管理我们的MySQL开发。我们只有一个master分支作为主干,不允许在主干上直接开发。每个同学根据feature和bug的issue建立分支,然后在分支上开发,不管开发过程中有多少个commit,我们要求最终提交每个bugfix或feature只能有一个提交。因此每个同学完成开发后,都需要git reset 退到最早的commit,git stash save宝存一下自己的修改,然后git checkout master; git pull拖一下最新的主干,然后返回自己的分支,再做git rebase master,把当前分支推进到主干,最后git stash pop弹出修改,有冲突则在当前分支解决,再git push。

# 此时commit id为a37b9ff,切换到开发版本dev
git checkout -b dev
# 实现了一个功能xxx,期间多次commit
...
# xxx开发完毕后,合并到主分支要求只有一个commit
git reset a37b9ff
git stash save "保存开发功能xxx的修改"
git checkout master
git pull
git checkout dev
git rebase master
git stash pop
# 处理冲突
git add .
git commit -m "功能xxx"
git checkout master
git merge --no-ff -m "merge 功能xxx" dev

4.5 常用分支命令

# 查看当前分支
git branch   
# 创建分支dev
git branch dev  
# 切换到分支dev
git checkout dev 
# 创建并切换到分支dev
git checkout -b dev 
# 合并指定分支(dev)到当前分支
git merge dev 
# 删除分支dev, 如果分支有未提交的这样删除不了
git branch -d dev
# 强制删除
git branch -D dev 
# 查看分支合并情况
git log --pretty=oneline --graph --abbrev-commit
# master转gh-pages
# 创建一个没有父节点的分支gh-pages
git checkout --orphan gh-pages

五、标签管理

5.1 常用标签命令

# 切换到要打标签的分支上
git branch
git checkout master

# 打标签
git tag v1.0

# 默认标签是打在最新提交的commit上,也可以指定commit id
# git log --pretty=oneline --abbrev-commit
git tag v0.9 <commit id>

# 查看标签列表
git tag

# 查看某标签信息
git show v0.9

# 标签加注释
git tag -a v0.1 -m "version 0.1 released" 2428164

# 可以用PGP签名标签
git tag -s v0.2 -m "signed version 0.2 released" fac145a

# 删除标签
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

六、使用GitHub

6.1 Fork/克隆

七、自定义Git

# 如果一个jar文件已经加到忽略文件里边了
# 想把一个jar文件添加到版本库
git add -f aaa.jar

八、问题

8.1 注释输入不了中文了

# Git安装目录 D:Program FilesGit
# 编辑如下文件D:Program FilesGitetcinputrc
# 确保如下行的配置如下,就可以保证输入中文注释了
set output-meta on
set convert-meta off

九、参考

原文地址:https://www.cnblogs.com/okokabcd/p/8576955.html