E哥的aws认证攻略 2019-07-01
本文由云+社区发表作者:工程师小熊
摘要:用了很久的Git和svn,由于总是眼高手低,没能静下心来写这些程序员日常开发最常用的知识点。现在准备开一个专题,专门来总结一下版本控制工具,让我们从git开始。完成本系列博客的阅读以后,你将掌握git的基本概念与git的基本命令,可以在本地随心所欲的完成代码的提交撤销保存修改等操作、可以流畅的参与多人协作,本文致力于快速的入门,如果涉及到更高级的功能需要进行更深一步的学习。
本文核心点:
git是世界上目前最先进的分布式版本控制系统,致力于团队、个人进行项目版本管理,完美的解决难以比较代码、难以合并代码、难以取消修改、难以在写当前代码的过程中保存未完成的修改去修改线上版本的bug等的痛点。
git是一个非常强大的工具,但作为一个git使用者来说,不用完全学习Git的知识点与命令,因为有的命令的使用频率非常的低甚至数年都不会用到,让我们来由浅入深进行学习。
git是linux的创始人linus,在付费版本控制工具BitMover收回对Linux社区免费使用权利的时候,一怒之下花费两个星期的时间写出来的。(牛笔的人)
选择自己的操作系统对应的git版本安装,安装成功后运行git version
后,输出git版本则安装正确。
git 官方: https://git-scm.com/downloads
使用git config
命令来配置用户名和邮箱
git config --global user.name "pzqu" git config --global user.email [email protected]
如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。
使用git config user.name
和git config user.email
来检查是否成功,也可以直接用git config --list
来列出全部git配置信息来查看
假如我们创建一个项目叫make_money,先创建一个文件夹叫make_money,再使用git init
命令创建git项目。
# pzqu @ pzqu-pc in ~/Documents/code/test [0:05:29] $ mkdir make_money # pzqu @ pzqu-pc in ~/Documents/code/test [0:06:24] $ ls make_money # pzqu @ pzqu-pc in ~/Documents/code/test [0:06:29] $ cd make_money # pzqu @ pzqu-pc in ~/Documents/code/test/make_money [0:07:10] $ git init Initialized empty Git repository in /Users/pzqu/Documents/code/test/make_money/.git/ # pzqu @ pzqu-pc in ~/Documents/code/test/make_money on git:master o [0:07:12] $ ls -al total 0 drwxr-xr-x 3 pzqu staff 96 11 7 00:07 . drwxr-xr-x 3 pzqu staff 96 11 7 00:06 .. drwxr-xr-x 9 pzqu staff 288 11 7 00:07 .git
创建成功以后,会出现一个叫.git的隐藏文件夹,这个就是你的git仓库,以后所有的git操作历史提交记录信息就全部记录在此了,只要这个文件夹在就可以记住我们的全部git操作
在使用git的时候还要清楚暂存区和工作区的含义,参考廖雪峰的官方网站-git篇-工作区和暂存区
# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [11:37:50] $ ls README.md # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [11:42:02] $ touch file1.txt # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [11:42:15] $ git add file1.txt # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [11:42:23] $ git status On branch master Your branch is up to date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: file1.txt # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [11:56:38] $ git commit -m "[+]add new file1.txt" [master 66cc488] [+]add new file1.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 file1.txt
上图操作包含:
git add .
:监控工作区的状态树,此命令会把工作时的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。
git add -u
:他仅监控已经被add的文件(即tracked file),他会将被修改的文件提交到暂存区。add -u 不会提交新文件(untracked file)。(git add --update的缩写)
git add -A
:是上面两个功能的合集(git add --all的缩写)
upload successful
git show 列出最近一次的提交
对于commit:像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [12:55:24] $ ls README.md file1.txt # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [12:55:25] $ git rm file1.txt rm 'file1.txt' # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [12:55:30] $ ls README.md # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [12:55:32] $ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: file1.txt # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master x [12:55:40] C:128 $ git commit -m "[-]delete file1.txt" [master e278392] [-]delete file1.txt 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 file1.txt
上图操作包含:
tip1: 如果没有用git rm删除文件,在本地删除文件后,git add一下再提交可以达到同样的效果
tip2: 要是你加班太晚,头晕不小心删除了不想删除的文件怎么办?见
下一篇:版本控制工具——Git常用操作(下)-后悔药
# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [17:01:13] $ git pull remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:pzqu/git_test 5fd4d8f..7b54a8a master -> origin/master Merge made by the 'recursive' strategy. share_file.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 share_file.txt
上图命令:
查看本地仓库变化git log
upload successful
上图可以看到向远程仓库pull的时候,出现了两个新的commit,commit 7b54a8ae74...
的提交信息为Create share_file.txt
,另一个commit fdbb19cf4c51770
的提交信息为Merge branch 'master' of github.com:pzqu/git_test
。事实上主线只有一个提交,为什么会出现这种情况? 是因为pull其实会做两个操作
注意这里的第二个个步骤如果远程有人和你改了同一个文件就会出现一个冲突,这个时候git会提示你哪些文件有冲突,手动改了再提交一次就可以了。详情见合并冲突
我在远程修改了文件,向share_file.txt
加了一行内容tom modify
,此时拉代码。
# pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [21:07:21] $ git fetch # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:master o [21:08:43] $ git rebase origin/master First, rewinding head to replay your work on top of it... Applying: [+]add new file1.txt Applying: [-]delete file1.txt
上图所示有以下两个操作
效果如下:
upload successful
上图是git log
所输出的提交内容,刚刚pull的时候忘记把pull自动产生的merge提交到远程,rebase的时候把本地的提交放到了远程提交之后,看起来就是一条直线,比较优雅,也是推荐的方式。
同样的,如果产生了冲突,详情见合并冲突
分支是多人协同最经典的地方所在,我们来创建一个分支
$ git checkout -b dev/pzqu origin/master Branch 'dev/pzqu' set up to track remote branch 'master' from 'origin'. Switched to a new branch 'dev/pzqu' $ git branch * dev/pzqu master
git checkout -b 分支名 其他分支
,-b
代表创建并切换到新建的分支,分支名
代表新创建的分支叫什么名字,这里叫dev/pzqu
,其他分支
代表基于哪一个分支来创建,这里基于远程的master分支origin/master
,如果省略则代表基于当前分支git branch
展示本地的分支情况,加-a
参数可以展示全部的分支,包括远程分支*
在分支前,指明了现在所在的分支是dev/pzqu
$ git checkout -b dev/pzqu2 Switched to a new branch 'dev/pzqu2' $ git branch dev/pzqu * dev/pzqu2 master $ git checkout dev/pzqu Switched to branch 'dev/pzqu' Your branch is up to date with 'origin/master'. $ git branch * dev/pzqu dev/pzqu2 master
dev/pzqu2
git checkout 已存在的分支名
切换分支回到dev/pzqu
$ git branch * dev/pzqu dev/pzqu2 master $ git branch -D dev/pzqu2 Deleted branch dev/pzqu2 (was 7c9be37). $ git branch * dev/pzqu master
dev/pzqu
,删除了dev/pzqu2
分支为了产生一个冲突,我在另一个地方向远程仓库提交了代码,更改share_file.txt
文件,加了一行内容tom add for merge
,
本地修改同一个文件加了一行pzqu add for merge
,并提交到本地,这样一来,本地和远程仓库的同一个文件就不一样了,一会拉代码一定会产生一个冲突。效果如下:
upload successful
upload successful
Git用<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容,我们修改如下后保存:
upload successful
git add
再git rebase --continue
后完成rebase,效果如下,再push
的远程仓库即可
upload successful
关于怎么创建分支与切换分支见创建分支和切换分支,这里只讨论合并时产生的冲突的情况,我们已经基于master
分支创建了一个dev/pzqu
分支
$ git branch * dev/pzqu master
切换到master
分支,加一行master add for merge
并提交,文件内容如下:
$ cat share_file.txt tom add tom modify tom add for merge pzqu add for merge master add for merge
切换到dev/pzqu
分支,向share_file.txt
加入一行dev/pzqu add for merge
并提交,现在share_file.txt
内容如下:
$ cat share_file.txt tom add tom modify tom add for merge pzqu add for merge dev/pzqu add for merge
现在两个分支的同一个文件内容不一样了,现在我们在dev/pzqu
分支上进行合并:
$ git merge master Auto-merging share_file.txt CONFLICT (content): Merge conflict in share_file.txt Automatic merge failed; fix conflicts and then commit the result. # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:dev/pzqu x [11:17:31] C:1 $ git status On branch dev/pzqu Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) 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: share_file.txt no changes added to commit (use "git add" and/or "git commit -a") $ cat share_file.txt tom add tom modify tom add for merge pzqu add for merge <<<<<<< HEAD dev/pzqu add for merge ======= master add for merge >>>>>>> master
上图出现了一个冲突,是我们意料之中的,修改share_file.txt
文件,解决此冲突:
$ cat share_file.txt tom add tom modify tom add for merge pzqu add for merge dev/pzqu add for merge master add for merge $ git add share_file.txt # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:dev/pzqu x [11:22:40] $ git commit -m "[*]merge master to dev/pzqu" [dev/pzqu d9e018e] [*]merge master to dev/pzqu # pzqu @ pzqu-pc in ~/Documents/code/test/git_test on git:dev/pzqu o [11:23:00] $ git status On branch dev/pzqu Your branch is ahead of 'origin/master' by 3 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean
冲突解决也提交了,看看我们现在的分支内容:
upload successful
上图我们可以看到:
master
分支比远程origin/master
分支多一次提交,dev/pzqu
分支由于是基于origin/master
分支,合并了master
分支的提交和当前dev/pzqu
分支的提交,超出本地master
两个提交,致此我们把master
合并到dev/pzqu
的操作就完成了。dev/pzqu
合并到master
分支,然后把两个分支都提交到远程。$ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) $ git merge dev/pzqu Updating 58f047a..d9e018e Fast-forward share_file.txt | 1 + 1 file changed, 1 insertion(+) $ git push origin master Total 0 (delta 0), reused 0 (delta 0) To github.com:pzqu/git_test.git 7c9be37..d9e018e master -> master $ git push origin dev/pzqu Counting objects: 9, done. Delta compression using up to 8 threads. Compressing objects: 100% (9/9), done. Writing objects: 100% (9/9), 887 bytes | 887.00 KiB/s, done. Total 9 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), done. remote: remote: Create a pull request for 'dev/pzqu' on GitHub by visiting: remote: https://github.com/pzqu/git_test/pull/new/dev/pzqu remote: To github.com:pzqu/git_test.git * [new branch] dev/pzqu -> dev/pzqu
master
分支dev/pzqu
到master
分支master
推到远程仓库dev/pzqu
要保留,就可以推送到远程仓库。upload successful
这种情况一般是出现在你正在完成一个功能,但是忽然线上发现了一个Bug,必须马上开一个新的分支来修复bug,但是现在的功能没写完不打算提交(commit),现在怎么办??不用怕暂存代码来帮助你。
$ git status On branch dev/pzqu Your branch is up to date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: need_stash.txt modified: share_file.txt $ git stash Saved working directory and index state WIP on dev/pzqu: d9e018e [*]merge master to dev/pzqu $ git stash list stash@{0}: WIP on dev/pzqu: d9e018e [*]merge master to dev/pzqu $ git status On branch dev/pzqu Your branch is up to date with 'origin/master'. nothing to commit, working tree clean //省略操作:去创建一个Bug分支,修复他并完成与主线的合并,删除Bug分支。 //省略操作:切回来当前分支继续开发 //下面来恢复现场 $ git stash apply stash@{0} On branch dev/pzqu Your branch is up to date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: need_stash.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: share_file.txt
status
查看到有2个文件修改没有提交stash
把修改放到暂存区,并生成一个idstash list
列出暂存区所有内容stash apply
重新把暂存区内容放到本地这里的stash apply
成功的把暂存区的一次暂存恢复到了本地,但是暂存区还有会保存这次暂存,如果想删除这次暂存要用git stash drop
来删除;也可以用git stash pop
,恢复最后一次暂存的同时把stash内容也删了。
$ git stash drop stash@{0} Dropped stash@{0} (bfdc065df8adc44c8b69fa6826e75c5991e6cad0) $ git stash list
好了,暂存区清干净了。
注意:要放到暂存区的文件一定要先通过git add加到index
本文阅读结束以后,我们学会了
Git常用操作(下)我计划给大家介绍以下点:
理论上,git日常用到的命令是 diff show fetch rebase pull push checkout commit status 等,这些命令都不会导致代码丢失,假如害怕代码丢失,可以预先commit一次,再进行修改,但切记
不可使用自己不熟悉的命令 任何命令,不要加上-f的强制参数,否则可能导致代码丢失
建议多使用命令行,不要使用图形界面操作
此文已由腾讯云+社区在各渠道发布
获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号及知乎机构号