前言
项目需要迭代
我们开发的应用程序是需要不断的迭代的,比如 version 1.0 、version 2.5 、version 3.9.11,这些指的都是版本号。不同版本号的应用程序,里面的功能都是不一样的,比如我们做一个名字叫做 project1 的应用,v1.0时可能仅仅只是基础框架,v1.1时增加用户中心模块,然后用了一段时间出现了一个致命的bug,然后我们把 project1 升级到了 v1.1.1 解决了这个bug,所以说应用程序是需要不断的迭代的。
版本管理
直接把项目复制出来一份,在副本项目中,直接做迭代,但这样做有一个坏处,如果升级的内容比较多,时间间隔又大的话,可能会忘记都做过什么事,这样就不便于管理了,所以应该选择一种更智能的方式管理我们的文件版本。
Git分布式版本控制系统
Git 的诞生
Git的三棵树
- 工作区:我们编写代码的文件具体存放位置。
- 暂存区:临时存储区域。
- 版本库:代码仓库,即分支。文件最终保存的区域。
安装 Git
mac 自带 git,windows 需要安装 git。
安装完成后,还需要最后一步设置,在命令行输入:
1 | git config --global user.name "Your Name" |
使用git config user.name或git config user.email可以查看用户名和邮箱。
创建本地仓库
创建文件夹,test_git
终端命令行输入:git init
1
git init #git初始化,不报错,代表初始化成功,会生成.git文件夹(是隐藏的)
如果报错,没有识别到git, 记得添加环境变量 …Git\bin
添加到暂存区
1
2
3git add . #提交所有变化的文件
git add abc #提交abc这个文件夹
git add *.css #提交所有css文件暂存区到代码库
1
2
3git commit -m '第一次提交' #默认以master主分支提交,记得添加提交的注释,便于分清楚提交时的信息
再修改一个文件
重新git add . git commit -m '第二次提交'执行一次查看提交历史
1
git log :查看提交日志
版本回溯
你看到的一大串类似3628164…882e1e0的是commit id(版本号)在Git中,用HEAD表示当前版本,上一个版本就是HEAD^ ,上上一个版本就是HEAD^^ ,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
1
2
3git reset --hard head^
或者不需要记忆次数,直接根据版本号前六位进行回退
git reset --hard 版本号前六位继续使用git log查看,发现撤销前的版本看不到了,想回回不去了,怎么办?
只能查看历史记录,找之前的版本号,
1
git reset --hard 版本号前六位
通过git reflog找版本号
1
2
3git reflog
再切换版本
git reset --hard 版本号前六位分支操作
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113创建分支
git branch 分支名
查看分支
git branch -v
git branch -av 含远程分支 没有连接远程则和上文没区别
切换分支fit
git checkout 分支名
合并分支
1. git checkout 接收修改的分支
2. git merge 新内容的分支
出现冲突,可以手动解决,之后
git add 文件名
git commit -m '日志' #注意,此时commit不要带具体文件名
删除不需要的分支
git branch -d branch_name
必须已经将分支完全合并到其上游分支或者HEAD中,否则不能成功。分支比较好理解,HEAD的场景工作中比较少遇到,比较不容易理解,所以我还特意在本地做了一个实验,实验前置条件:从master分支创建了一个新分支test,并在test产生一个commit,然后切回master分支,此时test是领先master一个commit的。
按照理解test直接用-d是删不掉的,那如何调整HEAD呢?利用前面学习的分离头指针!直接使用`git checkout 'test的commitID'`,这个时候`git log --all --graph`可以看到HEAD和test在同一个commit上,此时再次使用`git branch -d test`,奇迹发生了,成功删除了test分支。
修改最新commit的message
git commit --amend
命令应该是代替(或这说修改)上一次提交,不只是修改message。
比如上一次提交时有几个文件没有add以及commit,可以重新进行add之后再commit --amend提交。
但这次提交之后不会增加一次新的commit,而是相当于在上一次commit的基础上进行修改。
修改历史任意一次的 Commit message,通常用在还没有提交到集成分支之前:
`git rebase -i father_commit_id`
把连续多个commit整理成一个
git rebase -i 开始commit [结束commit], 在执行这个命令时,
如果没有指定 结束commit,那么结束commit 默认为当前分支最新的 commit,那么rebase 结束后会自动更新当前分支指向的 commit,
如果指定了结束 commit,而且结束 commit不是当前分支最新的 commit,那么rebase 后会有生成一个 游离的 head,,而且当前分支指向的commit 不会更新
把间隔几个commit整理成一个
如果要重写根提交(第一个提交),它并没有父节点,该怎么办?在提交列表中,可以手工将根提交添加进来。更简单的方式是使用 `git rebase -i --root` 命令,该命令允许你在分支上变基根提交。也就是说,Git 提供的提交列表会包含从根提交直到当前提交的所有提交。
比较暂存区和HEAD所含文件的差异
git diff --cached || git diff —cached
比较工作区和暂存区所含文件的差异
假定:HEAD、缓存区、工作区中的readme.md文件内容均不相同。
git diff HEAD -- readme.md # 工作区 <===> HEAD
git diff -- readme.md # 工作区 <===> 缓存区
git diff --cached -- readme.md # 缓存区 <===> HEAD
git reset 有三个参数
--soft 这个只是把 HEAD 指向的 commit 恢复到你指定的 commit,暂存区 工作区不变
--hard 这个是 把 HEAD, 暂存区, 工作区 都修改为 你指定的 commit 的时候的文件状态
--mixed 这个是不加时候的默认参数,把 HEAD,暂存区 修改为 你指定的 commit 的时候的文件状态,工作区保持不变
工作区恢复为暂存区一样
暂存区覆盖工作区修改:git checkout
Git 2.23之后用git switch和git restore来替代git checkout功能,git switch替换git checkout切换分支的功能,git restore替换对工作区文件进行恢复的功能。
取消暂存区部分文件的更改
git reset HEAD -- 文件名可单个可多个 将文件从暂存区指向工作区 前面和HEAD一致 后面指定具体要恢复的文件
修改了工作区,恢复:git checkout
add后,想撤销: git reset HEAD
commit后,想撤销: git reset--hard hash值
不同commit文件之间的差异
git diff hash1 hash2 --<file name>
删除文件(暂存区)
git rm filename
工作区先处理优先级高的任务 再来恢复到以前的状态
git stash
git stash list
git stash apply
git stash pop
本地模拟推送,git备份
## 远程库
git clone --bare file:///XXXX/.git remoteRepoName.git
bare不包含工作区,作为远端,以后备份方便一点
这样的话,已经备份了
## 本地仓库
跟远程库建立关联
git remote add remoteRepoName file:///XXXX/remoteRepoName.git
本地发送一些改动,比如新增分支develop
推送分支变动到远程
git push --set-upstream remoteRepoName develop
再到远程库下面查看就会发现远程也有develop分支了
多人单分支集成协作常见场景
不同人不同文件
如果在进行git push之前发现远程又有了更新,比较好的做法应该是,将本地的提交回退掉,避免掉无用的远程merge本地分支的提交记录,可以使用如下命令:
1.git reset HEAD~
2.git pull
然后重新进行新的提交,这样就可以避免掉远程与本地分支的merge提交记录,让git的提交历史更加干净
或者把本地的提交基于远端分支做 rebase ,在本地解决掉冲突并完成自测。
不同人相同文件不同区域
gitk --all 观察是否是fast-forward不是需要先fetch下来手动合并或pull之后再次push
不同人相同文件相同区域
手动处理冲突
修改了同一个文件相同地方,push时候 git merger 合并 everthing up to date, pull下来 手动合并解决冲突(和别人一起确认后合并,提交)
多人修改文件名情景
如果有些文件不想加入版本控制,也不想提交到远端,可以按如下步骤操作:
1.git ls-files查看暂存区内已进行版本控制的文件
2.git rm --cached 〈文件名〉将文件移除版本控制
3.编辑.gitignore文件,将不想加入版本控制的文件写进去,详细方法可参考github上的.gitignore文件。
Github进行团队协作
远程代码仓库
GitHub比较火,但毕竟是国外的网站,访问速度比较慢,所以也可以选择国内的码云
GitHub
gitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名gitHub。
2018年6月4日,微软宣布,通过75亿美元的股票交易收购代码托管平台GitHub。
远程库操作
1 | 查看远程库别名 |
生成本地密钥
创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有 id_rsa 和 id_rsa.pub 这两个文件,如果已经有了,可直接跳到下一步。
如果没有
1 | ssh-keygen -t rsa -C "1469720568@qq.com" |
你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,所以也无需设置密码。
如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
GitHub授权
登陆GitHub,打开“Account settings”,“SSH Keys”页面:
然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴 id_rsa.pub 文件的内容,点“Add Key”,你就应该看到已经添加的Key。
git使用原则
1 | git使用原则 |