.gitignore与分支
.gitignore
一般来说每个Git项目中都需要一个.gitignore文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中,比如Android项目中的iml文件及build目录下编译生成的文件,项目中经常会有很多临时文件, 如临时的编译中间文件, 通常这些文件不需要加入到版本控制中. 如何在提交的时候跳过这些文件? 一种办法是很繁琐的在 git add 的时候手动添加需要加入版本控制的文件, 这种方法不仅繁琐也很容易犯错.还有一个办法就是使用 gitignore 文件
哪些文件需要放入到.gitignore里
通常, 能够通过其他文件自动生成的都不需要放入版本控制, 如编译产生的临时文件.
还有, 操作系统会创建自动创建一些文件, 如缩略图, 这些也不需要放入版本控制
最后, 某些比较敏感的文件, 比如包含数据库连接密码的配置文件也不要放到公共 git 仓库里
不过, 并不是一定如此, 还是得具体问题具体分析
总结
- gitignore 是用来过滤不想加入版本控制的文件用的
- 可以找到很多现成的 gitignore 文件
- 你应该尽早编写gitignore并及时提交
具体操作讲解
创建一个properties文件
$ echo "my project configuration" > settings.properties查看状态
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
settings.properties
nothing added to commit but untracked files present (use "git add" to track)会显示这个properties文件一直处于是未追踪的状态,不管你以后是否提交了txt文件到版本库中,都会一直显示未追踪,但按理来说,我们不能将项目有关的配置文件提交到Git的版本库中,这时候就需要properties放进版本库
创建.gitignore
$ vim .gitignore查看文件以及git status
$ ls -al
total 59
drwxr-xr-x 1 A 197609 0 11月 15 20:34 ./
drwxr-xr-x 1 A 197609 0 11月 15 10:20 ../
drwxr-xr-x 1 A 197609 0 11月 15 20:29 .git/
-rw-r--r-- 1 A 197609 0 11月 15 20:34 .gitignore
-rw-r--r-- 1 A 197609 25 11月 15 20:29 settings.properties
-rw-r--r-- 1 A 197609 16 11月 14 17:17 test.txt
-rw-r--r-- 1 A 197609 13 11月 14 11:56 test2.txt$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
settings.properties
nothing added to commit but untracked files present (use "git add" to track)这时候我们再vim .gitignore
$ vim .gitignore在.gitignore里面加入文件名 settings.properties
$ cat .gitignore
settings.properties我们这时候再git status一下,就可以发现 settings.properties不见了
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
nothing added to commit but untracked files present (use "git add" to track)我们提交.gitignore到暂存区和版本库中
$ git add .gitignore
warning: LF will be replaced by CRLF in .gitignore.
The file will have its original line endings in your working directory$ git commit -m 'add .gitignore'
[master 095b97f] add .gitignore
1 file changed, 2 insertions(+)
create mode 100644 .gitignore查看一下
$ git status
On branch master
nothing to commit, working tree clean$ ls -al
total 60
drwxr-xr-x 1 A 197609 0 11月 15 20:37 ./
drwxr-xr-x 1 A 197609 0 11月 15 10:20 ../
drwxr-xr-x 1 A 197609 0 11月 15 20:42 .git/
-rw-r--r-- 1 A 197609 21 11月 15 20:37 .gitignore
-rw-r--r-- 1 A 197609 25 11月 15 20:29 settings.properties
-rw-r--r-- 1 A 197609 16 11月 14 17:17 test.txt
-rw-r--r-- 1 A 197609 13 11月 14 11:56 test2.txt可以发现,setting.properties文件还是在的,但是被Git给忽略掉了,说明我们的项目的配置文件,无论你做任何修改,Git都会忽略掉
再试一次
创建一个a.b文件
$ echo 'another file' > a.b$ cat .gitignore
settings.properties
a.b$ git add .
warning: LF will be replaced by CRLF in .gitignore.
The file will have its original line endings in your working directory$ git commit -m 'update .gitignore'
[master df216c5] update .gitignore
1 file changed, 1 insertion(+), 1 deletion(-)$ git status
On branch master
nothing to commit, working tree clean忽略文件
.gitignore文件
| *.a | 忽略所有.a结尾的文件 |
|---|---|
| !lib.a | 但lib.a除外 |
| /TODO | 仅仅忽略项目根目录下的TODO文件,不包括subdir/TODO |
| build/ | 忽略build/目录下的所有文件 |
| doc/*.txt | 会忽略doc/notes.txt但不包括doc/server/arch.txt |
例:
创建一个test3.txt,并且查看git status
$ echo 'test3' >test3.txt$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
test3.txt
nothing added to commit but untracked files present (use "git add" to track)修改一下.gitignore,再查看下git status
/test3.txt$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore发现test3.txt没了,但是这时候我们再创建一个mydir目录,在mydir里面创建一个mydirtest3.txt, 再查看git status
$ cat mydirtest3.txt
test3$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
mydir/注意:这时候我们在Gitfile根目录下进行git status与在mydir目录下进行git status是不一样的,对比效果如下:
Gitfile
.gitignore mydir/mydir
../.gitignore ./如果想把
mydirtest3.txt也忽略掉,可以在.gitignore里面添加:/*/mydirtest3.txt这样
mydirtest3.txt就忽略掉了,但如果我们每层目录下都要这样写,那样就很麻烦,例如:我们在mydirtest下面创建一个目录yourdir,然后在里面也创建一个test3.txt,查看一下:No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore mydir/我们想把所有目录下的
test3.txt都忽略掉,可以加上两个**/**/test3.txt这样就都忽略掉了
- build
如果我们在
.gitignore忽略文件前面加上#注释掉,则该忽略失效,我们想使一个目录下的所有文件都失效,可以这样:mydir/这样
mydir下面的所有文件就都忽略掉了
重要的分支
当我使用命令git init初始化一个Git厂库的时候,Git给我们初始化了一个master主分支,这时候我们如果想查看我们是在哪个分支,可以使用一个命令查看:
$ git branch如果想创建一个新的分支,则可以在命令后面加入参数,参数就是新的分支名字,列如:
$ git branch new_branch再使用git branch查看,就会发现多了一个分支了:
$ git branch
* master
new_branch注:如果我们最开始就git init一个Git厂库,啥都没有,然后就git branch是会报错的,那是因为你暂存区与版本库没有任何东西,所以想要创建新的分支,必须是要工作区的
在不同分支之间来回穿梭,与创建后立即进入
如果想在分支之间切换,则可以使用命令git checkout + 分支名,例:
$ git checkout new_branch
Switched to branch 'new_branch'checkout后面可以跟一个参数,就可以在创建一个新的分支后立即进入,这个参数就是-b,例:
$ git checkout -b new_branch
Switched to a new branch 'new_branch'如果也在此分支立刻返回到先前所在的分支,也如同切换文件一样,可以跟上-,例:当前我是在new_branch,想回到master
$ git checkout -
Switched to branch 'master'我们在不同的分支切换,其实就是在master与分支之间切换,在windows Mac或虚拟机的图形化界面下,查看Gitfile会发现在切换分支时,文件是都在Gitfile master那个页面中变幻,而不会是创建了新的文件夹,我们在另外的分支中创建文件,如果没有合并分支,在master中都是看不到的
删除分支
想要删除分支,要分为两种情况:无任何修改与已有修改
无任何修改的分支删除
如果我们创建一个分支,没有任何的修改,意思是跟master一样,想要删除这个分支,则直接在git branch后面加参数-d,例如下:
$ git branch -d new_branch
Deleted branch new_branch (was df216c5).这样new_branch就删除掉了
已有修改操作的分支删除
我们重新创建一个new_branch并且向里面添加一个test1.txt,让这个文件提交到版本库中,再使用-d参数试试:
已提交test1.txt到new_branch的版本库:
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (new_branch)
$ git commit -m 'new_branch test1.txt first'
[new_branch 5e0c211] new_branch test1.txt first
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test1.txt使用git log查看,可以很清楚的看到test1.txt是在new_branch提交的记录:
commit 5e0c211f1c85a429cf8458eeb91a40043aaca6be (HEAD -> new_branch)
new_branch test1.txt first我们回到master,试图用-d参数删除new_branch:
$ git branch -d new_branch
error: The branch 'new_branch' is not fully merged.
If you are sure you want to delete it, run 'git branch -D new_branch'.出现提示,提示你new_branch跟master是没有合并的两个分区,如果想在没合并的前提下删除new_branch,可以使用参数-D进行强制删除,那我们使用-D强制删除试试:
$ git branch -D new_branch
Deleted branch new_branch (was 5e0c211).$ git branch
* master发现new_branch已经删除了,并且先前在new_branch中提交test1.txt的git log也已经删除了,我们再创建new_branch与test1.txt这时候来合并试试,合并两个版本需要使用使用git merge这个命令,我们回到master使用
$ git merge new_branch
Merge made by the 'recursive' strategy.
test1.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test1.txt这时候发现我们的master中的test1.txt已经变为了new_branch中的test1.txt
这时候我们再调用-d参数,看是否能删除new_branch:
$ git branch -d new_branch
Deleted branch new_branch (was afa98a1).
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ git branch
* master我们可以使用-v参数查看当前分支最新的一条提交信息,例如:
$ git branch -v
* master f25e8c3 Merge branch 'new_branch' into master分支的本质
- 一个
commit对象链:一条工作记路线
Git每次提交都记录着上一次的提交ID,这样就形成了一条完整的时间线,每一次的Parent都指向上一次的提交ID
HEAD指向的是当前分支master指向提交
HEAD并不指向当前提交,而是指向当前分支,而master才是指向当前提交,所以HEAD指向master
dev的意思是指我使用git branch dev,是在这时候创建了一个dev分支,相当于你执行了git checkout -b dev这条命令,创建了dev分支并且进入了此分支,所以HEAD是指向dev的
而HEAD是在哪了?HEAD是在.git目录下,我们现在查看一下:
$ cd .git
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile/.git (GIT_DIR!)
$ cat HEAD
ref: refs/heads/master可以显示当前HEAD是指向的master
我们创建一个dev分支,再查看一下HEAD:
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ git checkout -b dev
Switched to a new branch 'dev'
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev)
$ cd .git
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile/.git (GIT_DIR!)
$ cat HEAD
ref: refs/heads/dev可以看到当前HEAD就是在dev了,就如图所示的样子了
此图显示的状态是,我们在dev分支上,又做了一次提交,就像我们在dev上面修改创建了一个文件,做了一次提交,所以我们如果在master上面使用git branch -d命令,会显示两个分支没有合并,只能使用git branch -D强制删除
我们可以使用git log对比一下master与dev的log:
dev:
commit 4ca3bca9404b69f665cb950903c332821987c58d (HEAD -> dev)
Author: YQHP-YuKi <************@qq.com>
Date: Thu Nov 19 15:05:19 2020 +0800
add new line on dev
commit f25e8c3063b088c3aa1f1239891538780c167cd2 (master)
Merge: 7d9a3e0 afa98a1
Author: YQHP-YuKi <************@qq.com>
Date: Tue Nov 17 23:18:47 2020 +0800
Merge branch 'new_branch' into master
commit 7d9a3e074e8c3265e416a738543d7c5cd820c9e0
Author: YQHP-YuKi <************@qq.com>
Date: Tue Nov 17 23:17:49 2020 +0800master:
commit f25e8c3063b088c3aa1f1239891538780c167cd2 (HEAD -> master)
Merge: 7d9a3e0 afa98a1
Author: YQHP-YuKi <************@qq.com>
Date: Tue Nov 17 23:18:47 2020 +0800
Merge branch 'new_branch' into master
commit 7d9a3e074e8c3265e416a738543d7c5cd820c9e0
Author: YQHP-YuKi <***********@qq.com>
Date: Tue Nov 17 23:17:49 2020 +0800
deledt .gitignore
commit afa98a1419abcd04ffdbd95d2398035e40f3b540
Author: YQHP-YuKi <************@qq.com>
Date: Tue Nov 17 23:11:40 2020 +0800
new_branch test1.txt second我们可以发现dev的第二条提交信息是master的第一条提交信息,dev第3条提交信息是master第2条提交信息
然后我们在master上面执行git merge
$ git merge dev
Updating f25e8c3..4ca3bca
Fast-forward
test.txt | 1 +
1 file changed, 1 insertion(+)显示更新了f25e8c3,我们再在master上面git log一下:
commit 4ca3bca9404b69f665cb950903c332821987c58d (HEAD -> master, dev)
Author: YQHP-YuKi <***********@qq.com>
Date: Thu Nov 19 15:05:19 2020 +0800
add new line on dev
commit f25e8c3063b088c3aa1f1239891538780c167cd2
Merge: 7d9a3e0 afa98a1
Author: YQHP-YuKi <***********@qq.com>
Date: Tue Nov 17 23:18:47 2020 +0800
Merge branch 'new_branch' into master
commit 7d9a3e074e8c3265e416a738543d7c5cd820c9e0
Author: YQHP-YuKi <***********@qq.com>
Date: Tue Nov 17 23:17:49 2020 +0800
deledt .gitignore可以发现master的log与dev的log已经相同了
两个分支不互通的情况
假如我们在master上面做了修改,也在dev上面做了修改,会发生什么了?
我们先修改master:
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ vim test.txt
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ git add .
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ git commit -m "this is master in test.txt"
[master 6162e11] this is master in test.txt
1 file changed, 1 insertion(+)
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ git status
On branch master
nothing to commit, working tree clean再在dev上面修改:
$ git checkout dev
Switched to branch 'dev'
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev)
$ vim test.txt
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev)
$ git add .
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev)
$ git commit -m 'this is dev in test.txt'
[dev 0a3a478] this is dev in test.txt
1 file changed, 1 insertion(+)我们回到master,尝试使用git merge试试:
$ git checkout master
Switched to branch 'master'
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ git merge dev
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.报错了,显示了在合并test.txt时,因为两个文件不符合,出现了报错
我们查看一下test.txt
$ cat test.txt
I am YQHP-YuKi
hello everyone
<<<<<<< HEAD
this is master
=======
this is dev
>>>>>>> dev因为HEAD代表的是当前分支,我们当前是在master,所以master的是this is master,dev的是this is dev,我们删除dev中的this is dev试试:
可以直接在master中vim test.txt,然后按dd删除:
$ cat test.txt
I am YQHP-YuKi
hello everyone
this is master查看一下状态:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")这时候我们使用git add这条命令,但这时的git add并非以前的git add意思,这时候的意思是告诉git我已经解决了这个冲突
$ git add test.txt
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master|MERGING)
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)我们使用git commit可以完成mearing:
$ git commit
[master a41fd9e] Merge branch 'dev' into master
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ git status
On branch master
nothing to commit, working tree clean保存退出文档即可
查看一下test.txt:
$ cat test.txt
I am YQHP-YuKi
hello everyone
this is master已经变为了master的了,我们git log一下:
master:
commit a41fd9e529c9a9e0b746745beae653b6736dac46 (HEAD -> master)
Merge: 6162e11 0a3a478
Author: YQHP-YuKi <***********@qq.com>
Date: Thu Nov 19 15:42:10 2020 +0800
Merge branch 'dev' into master
commit 0a3a478dc18d6b39a53e7ad3cbbecdda0531071a (dev)
Author: YQHP-YuKi <***********@qq.com>
Date: Thu Nov 19 15:25:09 2020 +0800
this is dev in test.txt
commit 6162e11b99c56f3e2e0f8c8bce933bbaa7081f26
Author: YQHP-YuKi <***********@qq.com>
Date: Thu Nov 19 15:22:15 2020 +0800
this is master in test.txt
commit 4ca3bca9404b69f665cb950903c332821987c58d
Author: YQHP-YuKi <************@qq.com>
Date: Thu Nov 19 15:05:19 2020 +0800dev:
commit 0a3a478dc18d6b39a53e7ad3cbbecdda0531071a (HEAD -> dev)
Author: YQHP-YuKi <**************@qq.com>
Date: Thu Nov 19 15:25:09 2020 +0800
this is dev in test.txt
commit 4ca3bca9404b69f665cb950903c332821987c58d
Author: YQHP-YuKi <**************@qq.com>
Date: Thu Nov 19 15:05:19 2020 +0800
add new line on dev
commit f25e8c3063b088c3aa1f1239891538780c167cd2
Merge: 7d9a3e0 afa98a1
Author: YQHP-YuKi <**************@qq.com>
Date: Tue Nov 17 23:18:47 2020 +0800
Merge branch 'new_branch' into master
commit 7d9a3e074e8c3265e416a738543d7c5cd820c9e0
Author: YQHP-YuKi <***************@qq.com>
Date: Tue Nov 17 23:17:49 2020 +0800会发现master比dev的更新记录更快一步,这一步是:Merge branch 'dev' into master,但现在两边的test.txt一样吗?查看下:
master:
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)
$ cat test.txt
I am YQHP-YuKi
hello everyone
this is masterdev:
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev)
$ cat test.txt
I am YQHP-YuKi
hello everyone
this is dev发现两边仍然不一样,那我们切换到dev试试在dev中git merge一下:
A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev)
$ git merge master
Updating 0a3a478..a41fd9e
Fast-forward
test.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)居然没有报错,并且成功的将master给合并过来了,这是为什么了?
合并讲解
这是最先我们dev与master都不一样的时候的样子,两个分支都有修改
这是我们在master进行了git add test.txt后的样子,相当于master向前跳了一个版本,但这个版本是跟一起那个master一样的,所以有这样的显示:Merge branch 'dev' into master,这样master就比dev更快一步了,并且两个分支建立了联系
我们再在dev中将master合并过来,这样使用git merge master或者在master中使用git merage dev就不会出现报错了,这样两个分支就完成合并了
参考资料
B站评论区大佬博客:https://www.cnblogs.com/AhuntSun-blog/p/12745183.html
git 官方文档: https://git-scm.com/docs/gitignore
segmentfault https://segmentfault.com/a/1190000000522997
廖雪峰的博客 : [http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013758404317281e54b6f5375640abbb11e67be4cd49e0000]