Git
基础概念
工作区
Git本地有四个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)、git仓库(Remote Directory)。文件在这四个区域之间的转换关系如下:
-
Workspace: 工作区,就是你平时存放项目代码的地方
-
Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
-
Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
-
Remote: 远程仓库,托管代码的服务器
工作流程
git的工作流程一般是这样的:
1、在工作目录中添加、修改文件;
2、将需要进行版本管理的文件放入暂存区域;
3、将暂存区域的文件提交到git仓库。
因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)
文件的四种状态
版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。
GIT不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用SHA-1算法计算文件的校验和。
- Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.
- Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified.
- Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过,返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
- Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存,文件状态为Modified
命令
git add
git add . 将所有文件从工作区加入暂存区
git rm
git rm -r -f --cached . 将所有文件从暂存区移除,需要重新使用git add
git commit
git commit -m 'message' 将文件从暂存区域移动至本地仓库,形成一个版本号
git commit --amend / git commit --amend -m 'message' 将本次暂存区的内容加入到上一次的commit中
vim 显示行号:set nu
git log
- git log 查询所有日志
空格 下一页
b 上一页
- git log --pretty=oneline 显示完整log信息(一行显示)
- git log --oneline 显示简略log信息
- git reflog 推荐使用
- git log --graph --pretty=oneline --abbrev-commit
图形化,查看分支合并情况
git reset
1、通过git reflog得到需要返回的版本号
2、git reset --hard [版本号]
note git reset --hard 会改变工作区的内容,所以慎重使用,最好先提交一个版本再使用。
git clone
- git clone [远程仓库地址]
git clone 这里做了三件事情
1. 把完整的远程代码下载到本地
2. 创建origin的远程地址别名
3. git init - git clone -b [远端分支] [远程仓库地址]
从远程仓库的某个分支下载
git branch
- git branch
查看本地分支 - git branch -r
查看远程分支 - git branch [name]
创建本地分支,注意新分支创建后不会自动切换为当前分支 - git branch -d [name]
删除分支,-d选项只能删除已经参与了合并的分支,对于未有合并的分支是无法删除的。如果想强制删除一个分支,可以使用-D选项 - git branch -vv
查看本地分支和远端分支的关联关系 - git branch --set-upstream-to=origin/[远端分支名] [本地分支名]
关联远端分支和本地分支
git checkout
- git checkout [分支名称]
切换到某个分支 - git checkout -b [分支名称]
创建一个本地分支并切换到此分支 - git checkout -- [文件名]
将暂存区的文件恢复到工作区
note慎重使用,会改变工作区的内容
git remote
- git remote -v
查看远程仓库 - git remote add [name] [url]
添加远程连接,name为别名,一般为origin - git remote rm [name]
删除远端仓库关联
git push
- git push [remoteName] [localBranchName]
推送远程仓库 - git push origin [name]
创建远程分支(本地分支push到远程)
$ git push origin test:master // 提交本地test分支作为远程的master分支 //好像只写这一句,远程的github就会自动创建一个test分支
$ git push origin test:test // 提交本地test分支作为远程的test分支
- git push origin :heads/[name]
git push -u origin mybranch1 相当于 git push origin mybranch1 + git branch --set-upstream-to=origin/mybranch1 mybranch1
删除远程分支
git differ
- git differ [文件名]
将工作区的文件和暂存区的文件比较 - git differ [本地库中的历史版本] [文件名]
将工作区的文件和其他版本中的比较
git pull
- git pull origin <远程分支名>:<本地分支名>
将远程指定分支 拉取到 本地指定分支上 - git pull = git fetch + git merge
git fetch后,需要先切换到fetch下来的分支,git checkout origin/[分支名],然后在git merge
Git中从远程的分支获取最新的版本到本地有这样2个命令:
- git fetch:相当于是从远程获取最新版本到本地,不会自动merge
Git fetch origin master
git log -p master..origin/master
git merge origin/master
以上命令的含义:
首先从远程的origin的master主分支下载最新的版本到origin/master分支上
然后比较本地的master分支和origin/master分支的差别
最后进行合并
上述过程其实可以用以下更清晰的方式来进行:
git fetch origin master:tmp
git diff tmp
git merge tmp
git rebase
合并commit
note git rebase 是把新的commit合并到老的commit上,但是代码是最新的。
1、查看日志,并记录日志编码
2、输入 git rebase -i [commit id]
输入的id是要合并的commit的前一条的id
3、修改文件类容,f是合并并舍弃当前commit,r是重新输入日志信息
4、对当前合并commit重新记录
5、success
6、如果在合并的过程中出错,使用git rebase --abort恢复
7、推送到远端
git push -f