Git常见问题

引子:git和svn的区别(集中式vs分布式),谈谈优劣?

廖雪峰 git集中式vs分布式
阮一峰 git分支管理策略

其中很显著的一点,就是版本的分支(branch)和合并(merge)十分方便。有些传统的版本管理软件,分支操作实际上会生成一份现有代码的物理拷贝,而Git只生成一个指向当前版本(又称”快照”)的指针,因此非常快捷易用。

工作区、暂存区、版本库的概念?

参考

分支的概念?

阮一峰 git分支管理策略
gitflow

git status 、git add 、git commit 三个命令的作用及区别,详细谈谈?

  • git status命令能展示工作目录和stage区的状态. 使用他你能看到那些修改被staged到, git status不显示已经commit到项目历史中去的信息. 看项目历史的信息要使用git log.参考

  • git add 文件welcome.txt从工作区被提交到暂存区,但此时文件并没有真正进入到版本库当中,文件目前只处于一个中间状态。

  • git commit(将暂存区文件提交到版本库中) 这个命令将处于中间状态的文件(暂存区的文件)提交到版本库中,这时才算真正完成了一次提交过程。

HEAD的概念

参考

HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长:

git中最常用的命令(12个)

常用Git命令清单by阮一峰

1
2
3
4
5
6
7
8
9
10
11
12
13
git status
git add
git commit

git checkout //切换到指定分支,并更新工作区
git reset //重制文件 重置暂缓区 工作区
git rm //删除工作区文件
git push //推送到远程仓库
git pull //拉取远程仓库
git clone //下载一个项目和它的整个代码历史
git branch //分支管理
git merge //合并冲突
git tag //标签管理

如何初始化项目,如何连接远程仓库?

  • 初始化一个空项目,所有的开发者clone到本地,这种方式自动连接到远程仓库
  • 本地目录下git init一个空项目,配置开发环境后 add–>commit; 新建一个远程仓库,使用git remote add ,连接到远程仓库,第一次推送 git push -u origin master

.gitignore文件的作用写法?

    1. 在已忽略文件夹中不忽略指定文件夹
1
2
/node_modules/*
!/node_modules/layer/
    1. 在已忽略文件夹中不忽略指定文件
1
2
/node_modules/*
!/node_modules/layer/layer.js

【注意项】注意写法 要忽略的文件夹一定要结尾 /* ,否则不忽略规则将无法生效

    1. 其他规则写法 (附)
1
2
3
4
5
6
7
8
9
10
11
12
 以斜杠“/”开头表示目录;

 以星号“*”通配多个字符;


 以问号“?”通配单个字符


 以方括号“[]”包含单个字符的匹配列表;


 以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;

Git冲突及如何解决冲突

Gti下游的概念

当dev分支是基于master分支,dev分支不断的commit,但是master分支没有修改,这时候可以直接合并分支,不会产生冲突。 即dev上的节点是master的下游时可以直接合并

当master也进行了commit, 这时候可能会产生冲突

merge的几种方式

  • fast-forword 快速合并, 改变HEAD指针指向
  • no-ff 新创建一个commit,再改变HEAD指针指向

git pull

拆分成两个操作: git fetch(拉取更新,新建一个分支) git merge(合并“远程分支”到本地master分支)

冲突发生的场景

  • 当需要合并分支的时候,另一个分支上的同一份代码已经被修改过

  • 执行git push, 提交代码时,最新仓库中的代码与本地工作区代码存在冲突

如何解决冲突

不借助第三方工具

廖雪峰git教程,分支合并解决冲突(场景一)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//新建并切换到新分支
git checkout -v dev

//修改data.js 并且add commit
git add data.js
git commit -m 'edit data'

//dev分支完成开发,此时检出到master分支
git checkout master

//修改master分支同一个文件,也add commit
git add data.js
git commit -m 'add something'

//尝试合并dev分支到master分支
git merge dev

//提示需要手动解决冲突,解决完成后,将修改到冲突文件add commit
git add data.js
git commit -m 'fixed merge'

//冲突解决之后,推送到远程仓库
git push

//当不在需要dev分支,则可以删除之
git branch -d dev

//如果仍然需要dev分支继续开发,则需要同步远程仓库到dev分支上
git pull orign master

借助第三方工具(场景二)

拉取远程仓库中最新的代码,提示冲突,查看冲突

1
2
3
git pull --rebase origin master
git status //查看当前冲突文件
git mergetool //打开diffmerge工具合并解决冲突

图形化工具diffmerge

下载地址DMG版
全局配置

1
2
3
4
5
6
git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.cmd "/Applications/DiffMerge.app/Contents/MacOS/diffmerge --merge --result=\$MERGED \$LOCAL \$BASE \$REMOTE"
git config --global mergetool.keepBackup false

git config --global diff.tool diffmerge
git config --global difftool.diffmerge.cmd "/Applications/DiffMerge.app/Contents/MacOS/diffmerge \$LOCAL \$REMOTE"

当出现冲突时,执行命令,弹出窗口手动解决冲突

1
$git mergetool

中间是合并后结果

完成合并,保存退出图形化工具
已经手动解决了冲突,这是让rebase继续工作,执行命令

1
2
3
git add <冲突文件/.  表示所有修改文件>
git rebase --continue //rebase继续工作
git push //代码成功提交

解决冲突中的异常处理

如果你碰到了冲突,但发现搞不定,不要惊慌。只要执行下面这条命令,就可以回到你执行git pull –rebase命令前的样子:

1
2
3
4
//解决冲突失败,或者向重新解决冲突
$git rebase --abort
//Skip是跳过这个错误,继续本次操作
$git rebase --skip

==git rebase –abort 是无风险的操作,会回到rebase操作之前的状态,2个分支的commits毫发无损。
git rebase –skip 是高风险的操作,引起冲突的commits会被丢弃(这部分代码修改会丢失)。==