Git 三个区域、四种状态
- 工作区(Working Directory)就是你在电脑里能看到的目录
- 版本库(Repository)工作区有一个隐藏目录
.git
,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage
(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。
Git相关命令操作
设置Git参数
# 显示当前的 Git 配置
git config --list
# 设置提交仓库时的用户名信息
git config --global user.name "fuziwang"
# 设置提交仓库时的邮箱信息
git config --global user.email "[email protected]"
三个区域、四种状态相关操作
# 在当前目录新建一个 Git 代码库
git init
# 添加指定文件到暂存区
git add [file1] [file2]
# 提交暂存区到仓库
git commit –m [message]
# 直接从工作区提交到仓库,前提该文件已经有仓库中的历史版本
git commit –a –m [message]
# 显示变更信息,可以展示四种状态的相关信息
git status
# 显示当前分支的历史版本
git log
git log --pretty=oneline "在一行显示"
# 记录你的每一次提交版本和回退版本的信息
git reflog
# 查看readme.txt文件在工作区和版本库里面最新版本的区别
git diff HEAD -- readme.txt
# 当对工作区进行修改之后,(不管上一次是否git add)还没有git add,丢弃对工作区的修改
git checkout -- [file]
# 当已经添加到暂存区,还没有git commit,可以把暂存区的修改撤销掉(unstage),重新放回工作区
git reset HEAD [file]
# 版本回退,一旦把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复
git reset --hard HEAD^
git reset --hard "commit-id"
# 删除工作区文件,并且将这次删除放入暂存区,之后只需要git commmit,不需要git add
git rm [file1] [file2]
# 改名文件,并且将这个改名放入暂存区,之后只需要git commmit,不需要git add
git mv [file-origin] [file-renamed]
Git分支管理
每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。在Git里,有一个主分支,即master
分支。HEAD
严格来说不是指向提交,而是指向master
,master
才是指向提交的,所以,HEAD
指向的就是当前分支。
每次提交,master分支都会向前移动一步,这样,随着版本的不断提交,master分支的线也越来越长:
Fast-forward
快速合并
# 创建dev分支,然后切换到dev分支
# git checkout命令加上-b参数表示创建并切换 相当于 git branch dev & git chekout dev
git checkout -b dev
# 查看当前分支是什么
git branch
# 把dev分支的工作成果合并到master分支上 git merge命令用于合并指定分支到当前分支
git merge dev
# 合并完成后,删除dev分支
git branch -d dev
# 如果要放弃分支的所有操作,不进行合并,强制删除分支的所有操作
git branch -D feature-vulcan
解决冲突
上述图片过程中会出现冲突,还原冲突过程:
- 准备新的
feature1
分支,对readme.md文件进行修改,并且在新的分支上进行了一次提交。 - 切换到
master
分支,同样对readme.me文件进行修改,并且在主分支上进行了一次提交。 - 此时进行合并,
git merge feature
运行这个命令会产生冲突,此时需要解决冲突
,需要手动修改文件内容。 - Git用
<<<<<<<,=======,>>>>>>>
标记出不同分支的内容,对文件进行修改后,再进行一次提交
用带参数的git log
也可以看到分支的合并情况
~/learngit(master) » git log --graph --pretty=oneline --abbrev-commit
* a0c8a45 conflict fixed
|\
| * a8b263e AND simple
* | 5565d9c & simple
|/
* faa2e24 branch test
...
--no-ff
方式的 git merge
- 创建并切换
dev
分支,修改readme.txt文件,并提交一个新的commit
- 切换回
master
,准备合并dev
分支,请注意--no-ff
参数,表示禁用Fast forward
合并后,我们用git log
看看分支历史:
~/learngit(master) » git log --graph --pretty=oneline --abbrev-commit
* fc2593c merge with no-ff
|\
| * ecca429 add merge
|/
* 2a45671 conflict fixed
...
Git stash
如果现在接到一个修复bug
的任务时,需要创建一个分支bug-1
来修复它,但是,当前正在dev
上进行的工作还没有提交,工作只进行到一半,还没法提交。此时需要去修复bug
,当前工作区需要暂时保存下来,等bug
修复完全再继续工作。
Git提供了一个stash
功能,可以把当前工作现场“储藏”
起来,等以后恢复现场后继续工作:
~/learngit(dev*) » git stash
Saved working directory and index state WIP on dev: ecca429 add merge
HEAD 现在位于 ecca429 add merge
此时可以进行bug
的修复。修复完成后,回到dev
开发工作中,用git stash list
命令看看当前保存的环境状态。
~/learngit(dev) » git stash list
stash@{0}: WIP on dev: ecca429 add merge
工作现场还在,Git把stash
内容存在某个地方了,但是需要恢复一下,有两个办法:
- 用
git stash apply
恢复,但是恢复后,stash
内容并不删除,你需要用git stash drop
来删除 - 用
git stash pop
,恢复的同时把stash
内容也删了
Rebase
对于该部分,可以看一下http://gitbook.liuhui998.com/...,我觉得这个讲解的更加清楚
rebase
操作可以把本地未push
的分叉提交历史整理成直线
,rebase
的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
应用场景:当本地比远程仓库多了几个提交之后,需要git push
,但当push
的时候发现,远程仓库已经有人先进行了推送,因此需要先pull
下来,此时输入git log --graph --pretty=oneline --abbrev-commit
会发现内容非常乱不好看,此时可以输入git rebase
~/learngit(master) » git rebase
First, rewinding head to replay your work on top of it...
Applying: add comment
Using index info to reconstruct a base tree...
M hello.py
Falling back to patching base and 3-way merge...
Auto-merging hello.py
Applying: add author
Using index info to reconstruct a base tree...
M hello.py
Falling back to patching base and 3-way merge...
Auto-merging hello.py
-----------------------------------------------------------
# 此时再输入git log命令会发现内容进行了整理
~/learngit(master) » git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master) add author
* 3611cfe add comment
* f005ed4 (origin/master) set exit=1
* d1be385 init hello
...
Git与GitHub
更多github的使用:http://developer.51cto.com/ar...
GitHub
这个网站就是提供Git仓库托管服务的,本地Git仓库和GitHub仓库
之间的传输是通过SSH
加密的,所以,需要一点设置:
第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa
和id_rsa.pub
这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
~ » ssh-keygen -t rsa -C "[email protected]"
在用户主目录里找到.ssh
目录,里面有id_rsa
和id_rsa.pub
两个文件,这两个就是SSH Key
的秘钥对,id_rsa
是私钥,不能泄露出去,id_rsa.pub
是公钥。
第2步:登陆GitHub,打开“Account settings”
,“SSH Keys”
页面:点“Add SSH Key”
,填上任意Title,在Key文本框里粘贴id_rsa.pub
文件的内容:
为什么GitHub需要SSH Key呢?
因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。GitHub允许添加多个Key。
提交代码到远程仓库
将远程仓库代码更新到本地
面试常考:讨论git pull
、 git fetch
的关系:
-
git fetch
相当于是从远程获取最新到本地,不会自动merge
-
git pull
:相当于是从远程获取最新版本并merge
到本地 在实际使用中,git fetch
更安全一些
Git命令操作
# 下载一个项目和它的整个代码历史
# url 格式: https://github.com/[userName]/reposName
git clone [url]
# 增加远程仓库,并命名
git remote add [shortname] [url]
# 将本地的提交推送到远程仓库
git push [remote] [branch]
推送分支:git push origin dev
# 将远程仓库的提交拉下到本地
git pull [remote] [branch]
# 查看远程库的信息,用git remote,或者,用git remote -v显示更详细的信息
git remote
~/learngit(master) » git remote -v
origin https://github.com/fuziwang/learngit.git (fetch)
origin https://github.com/fuziwang/learngit.git (push)
# 本地分支和远程分支的链接关系没有创建
git branch --set-upstream branch-name origin/branch-name