日常工作中常用Git命令小结

269 阅读8分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

正确理解Git的四个工作区域

Workspace:工作区,即个人克隆项目到本地后,项目所在的文件夹目录。

Index / Stage:暂存区,用于储存工作区中的变更(增删改等改动)的文件的地方。操作时使用git add会将本地所有的变更提交到暂存区中

Repository:仓库区(或版本库),用于储存工作区和暂存区中提交上来的文件,使用git commit -m '提交内容的描述',这里面有你提交到所有版本的数据,其中HEAD指向最新放入仓库的版本

Remote:远程仓库,当进行到这里的时候(即一个人的开发完毕时),需要将自己开发的功能合并到主项目中去,但因为是多人开发,要保管好主项目中存储的代码和文件的话,就需要放在搭建好的远程Git仓库中(即远程仓库)。具体操作:git push origin 远程分支名即可。

Git的一般工作流程

Git的工作流程一般是这样的:

  1. 在工作目录中添加、修改文件
  2. 在工作目录中添加、修改文件放入暂存区域
  3. 将暂存区域的文件提交到本地git仓库
  4. 将本地仓库的代码上传到远程仓库

文件的四种状态

版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。

GIT不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用SHA-1算法计算文件的校验和

  • Untracked:  未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制。通过git add 状态变为Staged.
  • Unmodify:  文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件
  • Modified:  文件已修改, 仅仅是修改, 并没有进行其他的操作。这个文件也有两个去处, 通过git add可进入暂存Staged状态, 使用git checkout则丢弃修改,返回到Unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
  • Staged:  暂存状态。执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态。执行git reset HEAD filename取消暂存,文件状态为Modified。

文件状态转变的流程图

这四种状态的转变流程图如下所示:

操作更改文件为xxx状态
新建文件Untracked
使用add命令将新建的文件加入到暂存区Staged
使用commit命令将暂存区的文件提交到本地仓库Unmodified
如果对Unmodified状态的文件进行修改Modified
如果对Unmodified状态的文件进行remove操作Untracked

因此,Git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)

新建仓库

  1. 建立远程库(远程库最好为空)

  2. 本地新建文件夹(最好与远程仓库同名的文件夹)

mkdir testgit
cd testgit
  1. 初始化仓库,当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的
git init  

注:

上面两步可合并为一步,新建一个目录,并将其初始化为Git代码库(git init [project-name]

  1. 关联远程库

git remote add origin(默认origin,可修改) branch_Name(为空时默认为master) url

git remote add origin git@github.xxx/xxx.git
# 两个地方的仓库名不需要相同,因为通过在本地仓库目录下执行这条
# 命令(命令中包含远程库的名字)已经将两者建立了联系
  1. 新增文件
touch README.md
  1. 添加文件到暂存区
git add .
  1. 提交文件到本地库
git commit -m "msg(提交日志)"

注:

上面两步可合并(git commit -am "msg"

  1. 把本地库的所有内容推送到远程库上
git push -u origin master 
# 加上了-u参数(推送和关联),Git不但会把本地的master分支内容推送到远程新的master分支,
# 还会把本地的master分支和远程的master分支关联起来
# 以后即可直接用git push代替git push origin master

克隆远程仓库

git clone git@github.com:xxx/xxx.git 

常用查看命令

# 查看仓库当前的状态
git status 

# 记录你的每一次命令,最先显示的是这个命令执行之后的版本的版本号的前七位
git reflog

比较文件不同-diff

# 查看对文件做什么修改,比较工作区和暂存区
git diff 文件名

# 比较暂存区与最新本地版本库
git diff --cached  filename

# 比较工作区和最新版本
git diff HEAD filename

# 比较工作区与指定的 commit -id 的差异
git diff commit-id  filename

# 比较暂存区与指定 commit-id 的差异
git diff --cached commit-id  filename

# 看两个版本的差异的文件列表,包括被修改行数和增删图
git diff 版本号1 版本号2 --stat
# git diff bf326a16 276b4a14 --stat
# docs/v2.8.76/README.md            | 10 ----------
# docs/v2.8.76/mysql_ddl.sql        |  6 ------
# 2 files changed, 16 deletions(-)

常用修改提交文件的命令

# 添加,但是不提交
git add readme.txt

# 提交,只有add后提交才有效。
# “改文件->add文件->再改->提交”,则第二次修改无效,不会被提交,只会成功提交第一次的修改。
git commit -m "提交描述"

撤销修改和版本回退(回滚)


# 本地通过git add & git commit 之后,想要撤销此次commit
# 回退到上一个版本
# 用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,
# 当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
git reset --hard HEAD^

# 回退到具体commit id
git reset --hard 0b3a6dbf02c8d03969577cb7fe0e200cf8303c63


# 本地修改/新增了一堆文件,已经git add到暂存区,想放弃修改。
# 单个文件/文件夹,把暂存的状态取消,工作区内容不变,但状态变为“未暂存”
git reset HEAD 文件名

# 所有文件/文件夹:
git reset HEAD .

# 本地修改了一堆文件(并没有使用git add到暂存区),想放弃修改
# 把没暂存(即没add)的干掉,或者说,丢弃工作区,回到到暂存状态
git checkout -- 文件名
# git checkout -- pom.xml

# 所有文件/文件夹
git checkout .

# 本地新增了一堆文件(并没有git add到暂存区),想放弃修改。
# 单个文件/文件夹:
$ rm filename 或者 rm -rf dir 

# 所有文件/文件夹:
$ git clean -xdf
// 删除新增的文件,如果文件已经已经git add到暂存区,并不会删除!

简单来说,没有add过的修改,只需要git checkout -- 文件名即可撤销; add 过的修改,先git reset HEAD 文件名变成没add 过的修改, 再git checkout -- 文件名 撤销。

实际案例:版本回滚及推送到远程仓库

# 第一步
# 查看提交的历史 
git log 
# 如果嫌上面的输出信息过多可以使用这条(只输出版本号) 
git log --pretty=oneline 

# 第二步
# 回到上个版本,git reset --hard HEAD^^是上上个版本
git reset --hard HEAD^
# 本地分支回滚到指定版本 
git reset --hard <commit ID号> 

# 第三步
# 强制推送到远程分支 
git push -f origin <branch name>

从远处仓库拉取到本地


# 从远程分支拉取代码,
# 缺点:会拉取当前项目的所有分支的commit。这样没必要,如当前项目有很多人在参与,
# 那么就会有很多分支,那么其他分支的提交也会拉取下来
git fetch	


# pull将代码直接合并,造成冲突等无法知道
git pull
# git fetch + git merge == git pull

操作远程仓库-remote

# 删除该远程库
git remote remove 远程库名 
# 例:git remote remove origin(一般都是叫origin)

# 添加另外远程库
git remote add 远程库名 远程库地址
# 例:git remote add origion https://...

# 改变远程库的名字
git remote rename 旧名称 新名称()
# 例:git rename origin origin1(把origin改成origin1)

# 查看远程库的信息
git remote 

# 查看远程库的信息地址,显示更为详细的信息,显示对应的克隆地址
git remote -v

# 更改remote地址
git remote set-url origin git@github.com:username/repository-name.git