# git篇

# 1. git 框架介绍(初级)

  • Workspace:开发者工作区。

  • Index / Stage:暂存区/缓存区。

  • Repository:仓库区(或本地仓库)。

  • Remote:远程仓库。

33

对应下面这张图可以知道 pull,fetch,checkout,push,commit,add的多个命令怎么进行操作了。

55

# 2. 列举工作中常用的几个 git 命令?(初级)

  • 新增文件的命令:git add file 或者 git add 。
  • 提交文件的命令:git commit –m 或者 git commit –a。
  • 查看工作区状况:git status –s。
  • 拉取合并远程分支的操作:git fetch/git merge 或者 git pull。
  • 查看提交记录命令:git reflog。

# 3. 提交时发生冲突,如何解决?(初级)

为什么会产生冲突?

因为在合并分支的时候,master 分支和 dev 分支恰好有人都修改了同一个文件,GIT 不知道应该以哪一个人的文件为准,所以就产生了冲突了。 两个分支相同文件相同位置的的不同操作!

如何解决?

发生冲突,在 IDE 里面一般都是对比本地文件和远程分支的文件,然后把远程分支上文件的内容手工修改到本地文件,然后再提交冲突的文件使其保证与远程分支的文件一致,这样才会消除冲突,然后再提交自己修改的部分。特别要注意下,修改本地冲突文件使其与远程仓库的文件保持一致后,需要提交后才能消除冲突,否则无法继续提交。必要时可与同事交流,消除冲突。

发生冲突,也可以使用命令。

  • 通过 git stash 命令,把工作区的修改提交到栈区,目的是保存工作区的修改。
  • 通过 git pull 命令,拉取远程分支上的代码并合并到本地分支,目的是消除冲突。
  • 通过 git stash pop 命令,把保存在栈区的修改部分合并到最新的工作空间中。

# 4. 新建 git 功能分支的步骤?(初级)

  • Git branch name 创建名字为 name 的 branch。
  • Git checkout xxx_dev 切换到名字为 xxx_dev 的分支。
  • Git pull 从远程分支拉取代码到本地分支。
  • Git checkout -b main_furture_xxx 创建并切换到 main_furture_xxx 分支。
  • Git push origin main_furture_xxx 执行推送的操作,完成本地分支向远程分支的同步。
  • 在执行 git pull 的时候,提示当前 branch 没有跟踪信息:
    • git pull origin 远程分支名称。
    • git branch --set-upstream-to=origin/远程分支名称 本地分支名(先建立远程分支与本地分支的连接,再pull)。
    • git pull 再 pull。

# 5. 说明 git 合并的两种方法以及区别(中级)

  • Git代码合并有两种:Git Merge 和 Git ReBase

    • Git Merge:这种合并方式是将两个分支的历史合并到一起,现在的分支不会被更改,它会比对双方不同的文件缓存下来,生成一个commit,去push。
    • Git ReBase:这种合并方法通常被称为“衍合”。他是提交修改历史,比对双方的 commit,然后找出不同的去缓存,然后去 push,修改 commit 历史。

# 6. Git提交代码的步骤(初级)

git clone (这个是你新建本地git仓库,如已有可忽略此步)
git pull    取回远程主机某个分支的更新,再与本地的指定分支合并。
git status  查看当前状态
git add + 文件
git add -u + 路径:将修改过的被跟踪代码提交缓存
git add -A + 路径: 将修改过的未被跟踪的代码提交至缓存
git add -u com/breakyizhan/src
将 com/breakyizhan/src 目录下被跟踪的已修改过的代码提交到缓存中
git commit -m "修复XXbug"   推送修改到本地git库中
git push    把当前提交到git本地仓库的代码推送到远程主机的某个远程分之上

# 7. fetch 和 merge 和 pull 的区别?(中级)

  • pull 相当于git fetch 和 git merge,即更新远程仓库的代码到本地仓库,然后将内容合并到当前分支。
  • git fetch:相当于是从远程获取最新版本到本地,不会自动 merge。
  • git merge : 将内容合并到当前分支。
  • git pull:相当于是从远程获取最新版本并 merge 到本地。

# 8. git 和 SVN 的区别(初级)

git 是分布式版本控制系统,SVN 是集中式版本控制系统。

# 9. git 的常用命令有哪些?(初级)

  • git show # 显示某次提交的内容 git show $id。
  • git add <file> # 将工作文件修改提交到本地暂存区。
  • git rm <file> # 从版本库中删除文件。
  • git reset <file> # 从暂存区恢复到工作文件。
  • git reset HEAD^ # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改。
  • git diff <file> # 比较当前文件和暂存区文件差异 git diff。
  • git log -p <file> # 查看每次详细修改内容的 diff。
  • git branch -r # 查看远程分支。
  • git merge <branch> # 将 branch 分支合并到当前分支。
  • git stash # 暂存。
  • git stash pop #恢复最近一次的暂存。
  • git pull # 抓取远程仓库所有分支更新并合并到本地。
  • git push origin master # 将本地主分支推到远程主分支。

# 10. 什么时候合并分支用 git rebase, 不用 git merge ?(中级)

git rebasegit merge 都可以用于合并分支,从 feature 分支上,取得新的提交 commits , 然后运用到 master 分支上(当然运用到其他分支上也行)。

但是路子不同,merge 是合并,rebase 是变基。

# 11. 变基怎么变?(高级)

64

看图可知: git rebase 有一个移动 base , 改变合并基准的操作。

直观的理解: git rebase 做的事情,就是先移指针,再移结点。

  • 先移指针:master 分支之前分出的 feature 分支的 commit id, 是 feature 分支的基准 base。

在 feature 分支上 git rebase master,就把 feature 分支的基准 base 移动到 master 分支最新的 commit id 上。

  • 再移结点: 把 feature 分支上新增的提交 commit id ,放到新的 base 结点后面。准确一些,就是把 feature 分支上新做的修改操作,重新应用到 master 分支的 HEAD 结点上。

举个例子

合并分支前:

A <- B <- C    [master]
^
 \
  D <- E       [branch]

根结点是 A, 最初是 A , 在 A 状态,分出去了分支 branch。

git merge 是这样合并的:

A <- B <- C
^         ^
 \         \
  D <- E <- F

提交到 C 的 master 分支和提交到 E 的 branch 分支,直接合并,一般是合并到 master, 有冲突解决冲突。

看图可知: 采用 git merge ,不改变原来的 commit id, 会产生新的提交 commit id

项目协作成员比较多,一般需要使用 git rebase, 当然也可以这样git merge, git merge --squash feeature

如果使用 git merge ,很可能这样:

64这样看,就很不舒服。需要采用 git rebase 修改历史:

git rebase 是这样合并的:

A <- B <- C <- `D` <- `E`

把 feature 分支( 例子中是 branch 分支)的提交 commits ,移动到 master 分支的顶端。

使用 rebase, 看起来更加 nice, 更加直观,历史就是一条直线嘛,没什么枝枝岔岔的。

看图可知: 使用 rebase 后,把 feature 分支上 commit 拿来后,commit id 改掉了。并且没有创建合并的公共节点 commit id

57

有的团队采用 git rebase 工作流,有的采用 git merge 工作流,git rebase 工作流要求对 git 的理解深一些,商用多一些, feature 做好了,用 git rebase 合并。

这样加 feature 怎么加的,看 log 比较明朗。否则看 log, 上一条 feature A, 下一条 feature B , 不是很职业程序员。

git rebase 工作流,一般这么实操, 在 feature 分支上 git rebase master, 切到 master 分支上后, git merge feature, 这时候 merge 也没做什么事情,就是把 master 分支的 HEAD 结点,移动到 feature 的 HEAD 结点, 两个分支这时候状态同步了。

git merge 工作流民用挺合适的,他的设计非常符合直觉,玩 github 开源,比较合适。因为多人写作,git flow 工作流,不是很好统一。

如果你采用 git rebase 工作流,你团队其他人不知道,你这么搞,commit id 修改了,与他们本地库的对不上,你们对你的意见可能会比较大

毕竟 git 采用分支,就是不冒犯别人代码的意思。