资料征引

知乎:git 兼并的时候如何只兼并部分文件?

廖雪峰:史上最深入浅出的Git教程!

作业区和暂存区

  • 作业区(Working Directory :在电脑里能看到的目录。
  • 版别库(Repository) :作业区有一个躲藏目录.git,这个不算作业区,而是Git的版别库。
  • 暂存区Git的版别库里存了很多东西,其中最重要的便是称为stage(或许叫index)的暂存区。

Git 入门速览

Git 入门速览

吊销修正

还未 add

# 假定修正了 readme.txt 文件,但还没有 git add,此刻经过 git status 指令来看看状况
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  # 廖雪峰老师的文章里git提示的吊销指令如下:
  (use "git checkout -- <file>..." to discard changes in working directory)
  # 但实践时我的git提示的吊销指令如下:
  (use "git restore <file>..." to discard changes in working directory)
        modified:   readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
# 现在丢掉作业区的修正
# 这儿 <file> 之前的 -- 很重要,缺少的话指令就变成了“切换到另一个分支”
git checkout -- readme.txt
# restore 指令功用同上
git restore readme.txt

这儿有两种状况:

  • 一种是<file>自修正后还没有被放到暂存区,吊销修正就回到和版别库相同的状况;
  • 一种是<file>现已添加到暂存区后,又作了修正,吊销修正就回到添加到暂存区后的状况。

总归,便是让这个文件回到最近一次git commitgit add时的状况。

现已 add 但没有 commit

# 假定修正了 readme.txt 文件,且执行了 git add,此刻经过 git status 指令来看看状况
$ git status
On branch master
Changes to be committed:
    # 廖雪峰老师的文章里git提示的吊销指令如下:
  (use "git reset HEAD <file>..." to unstage)
  # 但实践时我的git提示的吊销指令如下:
  (use "git restore --staged <file>..." to unstage)
        modified:   readme.txt
# 现在丢掉暂存区的修正
$ git reset HEAD readme.txt
Unstaged changes after reset:
M        readme.txt
# restore 指令作用同上
git restore --staged readme.txt

git reset指令既能够回退版别,也能够把暂存区的修正回退到作业区。当我们用HEAD时,表明最新的版别。

现已 commit 但没有 push

# 假定修正了 readme.txt 文件,且执行了 git add、git commit
# 此刻经过 git status 指令来看看状况
$ git status 
On branch <branch name>
nothing to commit, working tree clean
# 现在回退 commit 版别
# 1. 检查提交前史
git log
# 2. 从当时(HEAD)回退到某个之前的 commit_id
git reset --hard commit_id
# 3. 也能够检查指令前史,从而吊销第二步的回退
git reflog
# 4. 从 commit_id 回到 HEAD
git reset --hard HEAD

--hard外,可选的参数还有--soft

  • –-soft:回退到某个版别,只回退了commit的信息(只改变了HEAD指针的指向),不会清空暂存区(不会改变代码)。假如还要提交,直接commit即可;

  • -–hard:完全回退到某个版别,本地的源码也会变为上一个版别的内容,吊销的commit中所包含的更改被抹除去,整个暂存区洁净。

现已 push

# 1. 检查提交前史
git log
# 2. 从当时(HEAD)回退到某个之前的 commit_id,也能够用 --soft,自行挑选。
git reset --hard commit_id
# 3. --force 强制提交当时版别
git push origin <branch name> -f

分支办理

切换到指定版别

git checkout <commit id>

git checkout本质上是用版别库里的版别替换作业区的版别,因而无论是修正仍是删去作业区的内容,都能够“一键还原”。

创立并切换分支

git checkout -b <branch name>
# 相当于以下两条指令
git branch <branch name>
git checkout <branch name>

git checkout又是用来吊销修正,又是用来(创立)切换分支。同一个指令,有两种作用,有点令人迷惑。

实际上,切换分支这个动作,用switch更合理。

// 创立并切换分支
git switch -c <branch name>
// 切换到已有分支
git switch <branch name>

删去本地分支

git branch -d <branch name>
// 将 -d 改为 -D 可强制删去

检查当时分支

$ git branch
* dev // 当时分支前会有个 “*”
  master

检查当时分支的父分支

// 严厉来讲该指令是用来看 <branch name> 的操作记载的
// 只是能够经过在操作记载中寻觅创立分支的指令,从而得知父分支是哪个
git reflog show <branch name>

兼并/部分兼并

git merge 兼并

分支兼并,将A分支兼并到B分支。

// 切换到A分支
git checkout A
// 获取A分支最新代码
git pull
// 切换到B分支
git checkout B
// 获取B分支最新代码
git pull
// 兼并分支
git merge A

兼并有几种形式:

  1. Fast-forward:快进形式,也便是直接把B指向A的当时提交,所以兼并速度非常快。这种状况是由于从B上B1节点生成A分支后,只在A分支上有过提交,而直到将A兼并到B,B仍处于B1节点,这等价于一向就在B分支上做修正,A1节点即是B1节点,An节点即是Bn节点。
  2. 普通形式:B1节点生成A分支后,B和A都有新的操作,但两个分支的操作不涉及相同文件的修正,此刻兼并速度尽管不如快进形式快,可是不会引起抵触。
  3. 兼并抵触:这是由于在两个分支上对同一个文件有了不同的操作导致的,通常不合会以下面这种形式表现:
<<<<<<< HEAD
B 的操作
=======
A 的操作
>>>>>>> A

这种状况下需求手动修正抵触,再完成兼并操作。

兼并指定的文件

有时候想要兼并A分支指定的文件或许文件夹到B分支上去,例如兼并A分支的README.md文件到B分支上面。

// 切换到A分支
git checkout A
// 获取A分支最新代码
git pull
// 切换到B分支
git checkout B
// 获取B分支最新代码
git pull
// 兼并指定文件或许文件夹到分支
git checkout A README.md 

假如这儿想要兼并文件夹的话,比方src/views文件夹,能够将READMD.md换成文件夹src/views/**

吊销commit、add

假如兼并过错,那么就先吊销commit,然后吊销add。

// 吊销commit 
git reset --soft HEAD
// 吊销add
git reset HEAD
// 吊销指定的文件
git reset HEAD src/views/README.md

检查分支兼并状况

git log --graph --pretty=oneline --abbrev-commit
# --graph 伪图形化检查分支兼并图
# --pretty=oneline 单行省略显现(将不显现提交者和提交时间信息)
# --abbrev-commit 缩略显现版别ID

储藏

储藏当时操作

git stash

检查储藏列表

$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log

使用储藏

# 使用的一起删去缓存库房中的第一个stash
git stash pop
# 将缓存库房中的stash多次使用到作业目录中,但并不删去stash复制。
git stash apply
# 使用指定的stash
git stash apply stash@{0}
# 删去则经过
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
# 或许删去一切缓存的stash
git stash clear

遴选

复制一个特定的提交到当时分支

git cherry-pick <commit id>

删去 untracked files(未监控)文件

// 删去 untracked files
git clean -f
// 连 untracked 的目录也一起删掉
git clean -fd
// 连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)
git clean -xfd
// 在用上述 git clean 前,强烈建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nxfd
git clean -nf
git clean -nfd

检查子模块版别

// 两种方法
git submodule
git submodule status

删去tag(标签)

删去本地标签

$ git tag -d v1.1.0
$ git tag --delete v1.1.0

检查库房中的一切现有标签来检查标签是否被删去

$ git tag -l

删去长途标签

$ git push --delete origin v1.1.0