配置可参考:
配置name 及email:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
创建版本库:
通过git init命令把这个?录变成Git可以管理的仓库:
$ git init
提交出现错误: fatal: Unable to create 'E:/study_fold/GitReposity/.git/index.lock': File exists
$ rm -f index.lock
https://git-scm.com/book/zh/v2/Git
https://www.yiibai.com/git/git_push.html
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
工作区和暂存区
it和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
先来看名词解释。
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的learngit
文件夹就是一个工作区:
版本库(Repository)
工作区有一个隐藏目录.git
,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。
分支和HEAD
的概念我们以后再讲。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master
分支,所以,现在,git commit
就是往master
分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
Tips:
使1命令git add ,注意,可反复多次使用,添加多个文件;
使用命令git commit,完成。
使用命令git status查看工作空间状态
使用命令git log查看log(可用查版本号进行回退)
使用命令git reset回退
$ git add file1.txt
$ git add file2.txt
$ git add file3.txt
$ git commit -m "add 3 files."
$ git status
$ git log
$ git reset --hard 3628164(用git log 查询出来的版本号,无需写全)
rest 只是将本地commit并未push到远程仓库的代码reset到某一次commit。
当reset后悔了又想回退到rest之前版本:
step 1:列出commit log(即使reset前的也可以列出来)
git reflog
git reset --hard commitID
tip: add/commit
每次修改都要先add,再提交。
eg.第一次修改之后add,
未commit提交再一次修改,没有add.
commit提交只会提交第一次修改
push 到 master远程仓库:
推送到远程仓库
当你想分享你的项目时,必须将其推送到上游。 这个命令很简单:git push [remote-name] [branch-name]
。 当你想要将 master 分支推送到 origin
服务器时(再次说明,克隆时通常会自动帮你设置好那两个名字),那么运行这个命令就可以将你所做的备份到服务器:
$ git push origin master
只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。 阅读 Git 分支 了解如何推送到远程仓库服务器的详细信息。
git branch命令
git branch
命令用于列出,创建或删除分支。
示例
以下是一些示例 -
1. 查看当前有哪些分支
$ git branch
master
* wchar_support
上面显示结果中,当前有两个分支:master 和 wchar_support,当前在 wchar_support 分支上,它前面有个星号(*
)。
2. 新建一个分支
下面命令将创建一个分支:dev2 -
$ git branch dev2
3. 切换到指定分支
下面命令将切换到指定分支:dev2 -
$ git checkout dev2
$ # 再次查看分支
$ git branch
* dev2
master
wchar_support
4. 查看本地和远程分支
$ git branch -a
* dev2
master
wchar_support
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/wchar_support
5. 将更改添加到新建分支上
$ git status
On branch dev2
Untracked files:
......
$ git add newfile.txt
$ git commit newfile.txt -m "commit a new file: newfile.txt"
[dev2 c5f8a25] commit a new file: newfile.txt
1 file changed, 2 insertions(+)
create mode 100644 newfile.txt
$ git push origin dev2
Username for 'http://git.oschina.net': 769728683@qq.com
......
git merge
命令用于将两个或两个以上的开发历史加入(合并)一起。
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
$ git add readme.txt
$ git commit -m "branch test"
[dev b17d20e] branch test
1 file changed, 1 insertion(+)
现在,dev
分支的工作完成,我们就可以切换回master
分支:
$ git checkout master
Switched to branch 'master'
现在,我们把dev
分支的工作成果合并到master
分支上:
$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
小结
Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
创建与合并分支
在版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master
分支。HEAD
严格来说不是指向提交,而是指向master
,master
才是指向提交的,所以,HEAD
指向的就是当前分支。
一开始的时候,master
分支是一条线,Git用master
指向最新的提交,再用HEAD
指向master
,就能确定当前分支,以及当前分支的提交点:
每次提交,master
分支都会向前移动一步,这样,随着你不断提交,master
分支的线也越来越长:
当我们创建新的分支,例如dev
时,Git新建了一个指针叫dev
,指向master
相同的提交,再把HEAD
指向dev
,就表示当前分支在dev
上:
你看,Git创建一个分支很快,因为除了增加一个dev
指针,改改HEAD
的指向,工作区的文件都没有任何变化!
不过,从现在开始,对工作区的修改和提交就是针对dev
分支了,比如新提交一次后,dev
指针往前移动一步,而master
指针不变:
假如我们在dev
上的工作完成了,就可以把dev
合并到master
上。Git怎么合并呢?最简单的方法,就是直接把master
指向dev
的当前提交,就完成了合并:
所以Git合并分支也很快!就改改指针,工作区内容也不变!
合并完分支后,甚至可以删除dev
分支。删除dev
分支就是把dev
指针给删掉,删掉后,我们就剩下了一条master
分支:
真是太神奇了,你看得出来有些提交是通过分支完成的吗?
下面开始实战。
首先,我们创建dev
分支,然后切换到dev
分支:
$ git checkout -b dev
Switched to a new branch 'dev'
git checkout
命令加上-b
参数表示创建并切换,相当于以下两条命令:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
基于某一次提交创建新的branch:
git checkout master
git branch dev5 7d10d46d76
合并特定提交: cherry-pick
master, dev
dev上有 commit1, commit2
只想合并commit1 到master
git checkout master
git cherry-pick commit1ID
rebase 用法:
假设你现在基于远程分支”origin
“,创建一个叫”mywork
“的分支。
$ git checkout -b mywork origin
结果如下所示 -
现在我们在这个分支(mywork)做一些修改,然后生成两个提交(commit).
$ vi file.txt
$ git commit
$ vi otherfile.txt
$ git commit
... ...
但是与此同时,有些人也在”origin
“分支上做了一些修改并且做了提交了,这就意味着”origin
“和”mywork
“这两个分支各自”前进”了,它们之间”分叉”了。
如果你想让”mywork
“分支历史看起来像没有经过任何合并一样,也可以用 git rebase
,如下所示:
$ git checkout mywork
$ git rebase origin
这些命令会把你的”mywork
“分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到”.git/rebase
“目录中),然后把”mywork
“分支更新 到最新的”origin
“分支,最后把保存的这些补丁应用到”mywork
“分支上(即把 origin 上的修改应用到mywork,并且把自身补丁补上去)。
当’mywork
‘分支更新之后,它会指向这些新创建的提交(commit),而那些老的提交会被丢弃。 如果运行垃圾收集命令(pruning garbage collection), 这些被丢弃的提交就会删除.
现在我们可以看一下用合并(merge)和用rebase
所产生的历史的区别:
在rebase
的过程中,也许会出现冲突(conflict)。在这种情况,Git会停止rebase
并会让你去解决冲突;在解决完冲突后,用”git add
“命令去更新这些内容的索引(index), 然后,你无需执行 git commit
,只要执行:
$ git rebase --continue
这样git会继续应用(apply)余下的补丁。
在任何时候,可以用--abort
参数来终止rebase
的操作,并且”mywork
“ 分支会回到rebase
开始前的状态。
$ git rebase --abort
经常被问到如何从一个分支合并特定的commits到另一个分支。有时候你需要这样做,只合并你需要的那些commits,不需要的commits就不合并进去了。
- 合并某个分支上的单个commit
首先,用git log或GitX工具查看一下你想选择哪些commits进行合并,例如:
dd2e86 - 946992 -9143a9 - a6fd86 - 5a6057 [master]
76cada - 62ecb3 - b886a0 [feature]
比如,feature 分支上的commit 62ecb3 非常重要,它含有一个bug的修改,或其他人想访问的内容。无论什么原因,你现在只需要将62ecb3 合并到master,而不合并feature上的其他commits,所以我们用git cherry-pick命令来做:
git checkout master
git cherry-pick 62ecb3
这样就好啦。现在62ecb3 就被合并到master分支,并在master中添加了commit(作为一个新的commit)。cherry-pick 和merge比较类似,如果git不能合并代码改动(比如遇到合并冲突),git需要你自己来解决冲突并手动添加commit。
- 合并某个分支上的一系列commits
在一些特性情况下,合并单个commit并不够,你需要合并一系列相连的commits。这种情况下就不要选择cherry-pick了,rebase 更适合。还以上例为例,假设你需要合并feature分支的commit76cada ~62ecb3 到master分支。
首先需要基于feature创建一个新的分支,并指明新分支的最后一个commit:
git checkout -b newbranch 62ecb3
然后,rebase这个新分支的commit到master(--ontomaster)。76cada^ 指明你想从哪个特定的commit开始。
git rebase --onto master 76cada^
得到的结果就是feature分支的commit 76cada ~62ecb3 都被合并到了master分支。