版本控制工具——Git常用操作(上)
摘要:用了很久的Git和svn,由于总是眼高手低,没能静下心来写这些程序员日常开发最常用的知识点。现在准备开一个专题,专门来总结一下版本控制工具,让我们从git开始。完成本系列博客的阅读以后,你将掌握git的基本概念与git的基本命令,可以在本地随心所欲的完成代码的提交撤销保存修改等操作、可以流畅的参与多人协作,本文致力于快速的入门,如果涉及到更高级的功能需要进行更深一步的学习。
本文核心点:
- Git的基本概念
- 一个人使用Git时的代码版本控制--(提交、拉代码、分支操作)
- 多人合作时的代码版本控制--(合并冲突、暂存代码)
什么是Git
简介
git是世界上目前最先进的分布式版本控制系统,致力于团队、个人进行项目版本管理,完美的解决难以比较代码、难以合并代码、难以取消修改、难以在写当前代码的过程中保存未完成的修改去修改线上版本的bug等的痛点。
git是一个非常强大的工具,但作为一个git使用者来说,不用完全学习Git的知识点与命令,因为有的命令的使用频率非常的低甚至数年都不会用到,让我们来由浅入深进行学习。
git的历史
git是linux的创始人linus,在付费版本控制工具BitMover收回对Linux社区免费使用权利的时候,一怒之下花费两个星期的时间写出来的。(牛笔的人)
开始
安装git
选择自己的操作系统对应的git版本安装,安装成功后运行git version
后,输出git版本则安装正确。
git 官方: https://git-scm.com/downloads
配置用户信息
使用git config
命令来配置用户名和邮箱
git config --global user.name "pzqu"
git config --global user.email pzqu@example.com
如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。
使用git config user.name
和git config user.email
来检查是否成功,也可以直接用git config --list
来列出全部git配置信息来查看
img
创建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.txt1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 file1.txt
上图操作包含:
- 创建新文件file1.txt
- add 添加修改的内容到索引
- status 查看修改的内容
- commit 把索引提交到本地分支
git add .
:监控工作区的状态树,此命令会把工作时的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。
git add -u
:他仅监控已经被add的文件(即tracked file),他会将被修改的文件提交到暂存区。add -u 不会提交新文件(untracked file)。(git add --update的缩写)
git add -A
:是上面两个功能的合集(git add --all的缩写)
img
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.txt1 file changed, 0 insertions(+), 0 deletions(-)delete mode 100644 file1.txt
上图操作包含:
- 创建新文件file1.txt
- git rm 删除file1.txt文件
- status 查看修改的内容
- commit 把索引提交到本地分支
tip1: 如果没有用git rm删除文件,在本地删除文件后,git add一下再提交可以达到同样的效果
tip2: 要是你加班太晚,头晕不小心删除了不想删除的文件怎么办?见
下一篇:版本控制工具——Git常用操作(下)-后悔药
拉代码
方法一 pull
# 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_test5fd4d8f..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 pull
查看本地仓库变化git log
img
upload successful
上图可以看到向远程仓库pull的时候,出现了两个新的commit,commit 7b54a8ae74...
的提交信息为Create share_file.txt
,另一个commit fdbb19cf4c51770
的提交信息为Merge branch 'master' of github.com:pzqu/git_test
。事实上主线只有一个提交,为什么会出现这种情况? 是因为pull其实会做两个操作
- 拉远程仓库代码到本地
- 自动与当前分支合并并生成一个合并成功的提交
注意这里的第二个个步骤如果远程有人和你改了同一个文件就会出现一个冲突,这个时候git会提示你哪些文件有冲突,手动改了再提交一次就可以了。详情见合并冲突
方法二 fetch
我在远程修改了文件,向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
上图所示有以下两个操作
- fetch 拉取远端代码到本地
- rebase 把本地代码提交基于远端分支重新replay
效果如下:
img
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/pzqumaster
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 branchdev/pzqu
* dev/pzqu2master$ git checkout dev/pzqu
Switched to branch 'dev/pzqu'
Your branch is up to date with 'origin/master'.$ git branch
* dev/pzqudev/pzqu2master
- 基于当前分支创建了一个新的分支并自动切换过去
dev/pzqu2
git checkout 已存在的分支名
切换分支回到dev/pzqu
删除分支
$ git branch
* dev/pzqudev/pzqu2master$ git branch -D dev/pzqu2
Deleted branch dev/pzqu2 (was 7c9be37).$ git branch
* dev/pzqumaster
- 位于
dev/pzqu
,删除了dev/pzqu2
分支
合并冲突
合并同一个分支的冲突(常见)
为了产生一个冲突,我在另一个地方向远程仓库提交了代码,更改share_file.txt
文件,加了一行内容tom add for merge
,
本地修改同一个文件加了一行pzqu add for merge
,并提交到本地,这样一来,本地和远程仓库的同一个文件就不一样了,一会拉代码一定会产生一个冲突。效果如下:
img
upload successful
- 一般rebase或pull冲突的时候,都会出现提示,然后git status会出现上图图示
- 这个时候不可以进行任何分支切换和commit操作,按照他提示进行处理
- git status提示哪个文件是都被修改的,both modified,然后使用编辑器修改该文件,解决冲突
- 解决完成后,git add 添加该冲突文件
- git rebase --continue,并更新commit message,完成整个rebase流程 我们来看看这个冲突的文件:
img
upload successful
Git用<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容,我们修改如下后保存:
img
upload successful
git add
再git rebase --continue
后完成rebase,效果如下,再push
的远程仓库即可
img
upload successful
合并不同分支的代码产生冲突
关于怎么创建分支与切换分支见创建分支和切换分支,这里只讨论合并时产生的冲突的情况,我们已经基于master
分支创建了一个dev/pzqu
分支
$ git branch
* dev/pzqumaster
切换到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.txtno 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
冲突解决也提交了,看看我们现在的分支内容:
img
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-forwardshare_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.git7c9be37..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
要保留,就可以推送到远程仓库。
img
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.txtmodified: 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.txtChanges 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的作用、历史;学会安装配置Git,使用Git创建项目托管以及工作区和暂存区的概念
- 学会Git的本地操作,提交、拉代码、创建切换删除分支操作,
- 多人合作时的代码版本控制,学会了不同情况下的合并冲突、暂存代码操作
下集预告
Git常用操作(下)我计划给大家介绍以下点:
- 后悔药-各种后悔操作(撤消commit,回滚,回退远程仓库等)
- 哎呀,提交的时候漏了文件
- tag操作
- git忽略不想提交的文件
注意事项
理论上,git日常用到的命令是 diff show fetch rebase pull push checkout commit status 等,这些命令都不会导致代码丢失,假如害怕代码丢失,可以预先commit一次,再进行修改,但切记
不可使用自己不熟悉的命令 任何命令,不要加上-f的强制参数,否则可能导致代码丢失
建议多使用命令行,不要使用图形界面操作
版本控制工具——Git常用操作(上)相关推荐
- 版本控制工具——Git常用操作(下)
本文由云+社区发表 作者:工程师小熊 摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码.使用分支.出现代码冲突的解决办法.紧急保存现场和恢复现场的操作.学会以后已经 ...
- 版本控制工具Git 常用操作命令
2019独角兽企业重金招聘Python工程师标准>>> Git 是用于Linux 内核开发的版本控制工具.与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式 ...
- iOS系列开发-版本控制工具Git的使用
iOS系列开发-版本控制工具Git的使用 作为一个开发者,与团队之间默契的配合是很重要的,我们所写的代码在无论是在公司还是在个人来说都是一份不可随意丢弃的东西,但是如果只是单纯的开发,我们很难做到今天 ...
- 版本控制工具Git(完美整理版)
版本控制Git 一.Git是什么 版本控制工具!Git是目前世界上最先进的分布式版本控制系统(没有之一). 这个软件用起来就应该像这个样子,能记录每次文件的改动 这样,你就结束了手动管理多个" ...
- Node.js Git Server搭建及Git常用操作笔记
Node.js Git Server搭建及Git常用操作笔记 安装Git工具即可在本地进行Git仓库的管理,如果要实现远程仓库则需要搭建Git Server.通过Node.js搭建Git Server ...
- Linux | 分布式版本控制工具Git【版本管理 + 远程仓库克隆】
文章目录 一.前言 二.有关git的相关历史介绍 三.Git版本管理 1.感性理解 -- 大学生实验报告 2.程序员与产品经理 3.张三的CEO之路 -- 版本管理工具的诞生 四.如何在Linux上使 ...
- git 常用操作总结——基于Gitlab
博主目前在蚂蚁集团-体验技术部,AntV/S2 是博主所在团队的开源项目--多维交叉分析表格,欢迎使用,感谢到 S2 github 仓库点赞 star,有任何关于前端面试.就业.技术问题都可给在文章后 ...
- git报错:‘fatal:remote origin already exists‘怎么处理?附上git常用操作以及说明。
git添加远程库的时候有可能出现如下的错误, 怎么解决? 只要两步: 1.先删除 $ git remote rm origin 2.再次执行添加就可以了. ---------------------- ...
- 版本控制工具Git详细介绍和常用命令
一.安装Git 在linux系统使用非常方便,只需要打开shell界面,并输入: sudo apt-get install git-core 按下回车后输入密码,即可完成Git的安装.但我们可能更多情 ...
- Git 常用操作(1)- 配置、查看、添加、暂存和提交
1. Git 基本概念 Git 有三种状态:已提交(committed).已修改(modified)和已暂存(staged). 已提交:表示数据已经安全的保存在本地数据库中. 已修改:表示修改了文件, ...
最新文章
- jenkins页面中英文切换配置
- spring boot的热加载(hotswap)
- 用于传递列表作为选项的argparse选项
- android studio 显示view树_Android 沉浸式解析和轮子使用
- python做动态相册_动感网页相册 python编写简单文件夹内图片浏览工具
- c++学习笔记之类和对象的进阶
- apache camel_Apache Camel日志组件示例
- matlab按某一列排序
- Python机器学习:梯度下降法003线性回归中的梯度下降法
- 计算机网络机械特性是指,《计算机网络与通信》第1——3章 习题及思考题
- c++之友元函数和友元类
- 深度解析MySQL启动时报“The server quit without updating PID file”错误的原因
- gltf、glb模型下载
- lwj_C#_集合listT
- MySQL之查询关键字
- 我要偷偷的学Python,然后惊呆所有人(第三天)
- python怎么横着输出_对python3中, print横向输出的方法详解
- 手机实现远程桌面控制
- 智能工厂 | 工业4.0
- 机器学习算法-EM算法
热门文章
- 解决Charles Response 中文乱码
- 打车软件是不是一个市场泡沫?
- 剖析Disruptor:为什么会这么快?(一)Ringbuffer的特别之处
- 一行代码迁移TensorFlow 1.x到TensorFlow 2.0
- 小红书创始人瞿芳回应裁员风波:战略部署清晰 人员翻倍
- 一步步打造一个移动端手势库
- Ubuntu 14.04安装LAMP(Linux,Apache,MySQL,PHP)
- DigitalOcean发布弹性块存储服务
- JAVA 中一个非常轻量级只有 200k 左右的 RESTful 路由框架
- QuickFlowDesigner教程(4)如何用代码控制活动操作人