本文由云 + 社区发表
摘要: 用了很久的 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 配置信息来查看
创建 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
上图操作包含:
创建新文件 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 的缩写)
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
上图操作包含:
创建新文件 file1.txt
Git rm 删除 file1.txt 文件
status 查看修改的内容
commit 把索引提交到本地分支
tip1: 如果没有用 Git rm 删除文件, 在本地删除文件后, Git add 一下再提交可以达到同样的效果
tip2: 要是你加班太晚, 头晕不小心删除了不想删除的文件怎么办? 见
- # 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
- # 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
- $ 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 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
- $ Git branch
- * dev/pzqu
- dev/pzqu2
- master
- $ Git branch -D dev/pzqu2
- Deleted branch dev/pzqu2 (was 7c9be37).
- $ Git branch
- * dev/pzqu
- master
- $ Git branch
- * dev/pzqu
- master
- $ cat share_file.txt
- tom add
- tom modify
- tom add for merge
- pzqu add for merge
- master add for merge
- $ cat share_file.txt
- tom add
- tom modify
- tom add for merge
- pzqu add for merge
- dev/pzqu add for merge
- $ 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
- $ 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
- $ 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
- $ 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
- $ Git stash drop stash@{
- 0
- }
- Dropped stash@{
- 0
- } (bfdc065df8adc44c8b69fa6826e75c5991e6cad0)
- $ Git stash list
来源: https://www.cnblogs.com/qcloud1001/p/10494832.html