使用Git的第一件事就是设置你的名字和email
,这些就是你在提交commit
时的签名,每次提交记录里都会包含这些信息。使用git config
命令进行配置:
$ git config --global user.name "xaiopang"
$ git config --global user.email "****@qq.com"
不知道大家注意到没有,这里怎么会有--global,这是什么鬼?问得好,因为上面的配置文件就是Git的全局配置,一般配置方法是git config --global <配置名称> <配置的值>
。如果你只是在当前项目中配置git config,可以不带 --global
选项。
内容一般像下面这样,可以使用vim或cat查看文件内容:
$ cat ~/.gitconfig
[user]
email = ****@qq.com
name = xaiopang
当你兴高采烈的在当前文件夹,打开CMD输入这两行代码时,是不是出错了,错误代码是:fatal: not in a git directory。意思就是我们需要一个git仓库。
有两种方法可以得到它:一种是从已有的Git仓库中clone (克隆,复制);还有一种是新建一个仓库,把未进行版本控制的文件进行版本控制。
为了得到一个项目的拷贝(copy),我们需要知道这个项目仓库的地址(Git URL). Git能在许多协议下使用,所以Git URL可能以ssh://, http(s)://, git://. 有些仓库可以通过不只一种协议来访问。
下图是我演示的例子 在git clone 后输入你自己的仓库地址,这时会提示你输入密码,填好密码后,clone完成。本地会新生成文件夹,一般是一个 .git文件夹和一个README.md文件。
可以对一个已存在的文件夹用下面的命令让它置于Git的版本控制管理之下。
创建代码目录project
:
class="hljs ruby">$ cd /home/shiyanlou/
$ mkdir project
进入到代码目录,创建并初始化Git仓库:
$ cd project
$ git init
Git会输出:
Initialized empty Git repository in /home/shiyanlou/project/.git/
通过ls -la
命令会发现project目录下会有一个名叫.git
的目录被创建,这意味着一个仓库被初始化了。可以进入到.git
目录查看下有哪些内容。
git的基本流程如下:
git add
命令添加新创建或修改的文件到本地的缓存区(Index)git commit
命令提交到本地代码库git push
命令将本地代码库同步到远端代码库接上文,新建一个文件夹project,然后在该文件夹中打开cmd,创建并初始化git仓库:
$ git init
此时你会发现project目录下会有一个名叫.git
的文件夹。接下来我们来创建文件 file1,file2,file3
$ touch file1 file2 file3
接下来修改文件,你可以使用编辑器修改,也可以直接echo添加测试内容
$ echo "test" >> file1
$ echo "test" >> file2
$ echo "test" >> file3
接下来可以使用git status
命令查看当前git仓库的状态:
$ git status On branch master Initial commit Untracked files: (use "git add <file>...") to include in what will be committed) file1 file2 file3 nothing added to commit but untracked files present (use "git add" to track)
可以发现,有三个文件处于untracked
状态,下一步我们就需要用git add
命令将他们加入到缓存区(Index)。
使用git add
命令将新建的文件添加到缓存区:
$ git add file1 file2 file3
然后再次执行git status
就会发现新的变化:
$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: file1 new file: file2 new file: file3
接下来就可以使用 git commit 把代码提交到本地仓库了, m后面的引号中的内容是此次修改的注释。
$ git commit -m "add 3 files"
此时我们的代码还在本地仓库,接下来就需要将本地仓库关联到远端服务器,我们可以使用 git remote
命令。
Administrator@USER-20150628OI MINGW64 /h/000git2/project (master)
$ git remote add origin https://gitee.com/******/test.git
git remote add
命令用于添加远程主机,origin
是主机名,此处我们可以自定义,不一定非要使用 origin
,而 https://gitee.com/******/test.git
,是我自己的远程仓库地址,此处 需要替换为你自己的远程仓库地址。
这个时候如果本地的仓库连接到了远程Git服务器,可以使用下面的命令将本地仓库同步到远端服务器了:
$ git push origin master
等等。。。。。怎么出错了.
Administrator@USER-20150628OI MINGW64 /h/000git2/project (master)
$ git push origin master
To https://git.coding.net/*****/mmav1.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://git.coding.net/******/mmav1.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
上面是我在学习的时候出的错误,网上百度了下 找到了解决方法:
原因就是线上仓库中的README.md文件不在本地仓库的文件夹中。
cmd中执行以下命令,进行代码合并【注:pull=fetch+merge]
$ git pull --rebase origin master
执行上面代码后可以看到本地代码库中多了README.md文件
此时再执行语句 $ git push -u origin master即可完成代码上传到线上仓库,此时在线仓库中就会多出三个文件,说明本地仓库同步到远端服务器已经成功了。
Git的分支可以让你在主线(master分支)之外进行代码提交,同时又不会影响代码库主线。分支的作用体现在多人协作开发中,比如一个团队开发软件,你负责独立的一个功能需要一个月的时间来完成,你就可以创建一个分支,只把该功能的代码提交到这个分支,而其他同事仍然可以继续使用主线开发,你每天的提交不会对他们造成任何影响。当你完成功能后,测试通过再把你的功能分支合并到主线。
一个Git仓库可以维护很多开发分支。现在我们来创建一个新的叫 experimental的分支:
$ git branch experimental
运行git branch
命令可以查看当前的分支列表,以及目前的开发环境处在哪个分支上:
$ git branch
experimental
* master
experimental 分支是你刚才创建的,master分支是Git系统默认创建的主分支。星号标识了你当工作在哪个分支下,输入git checkout 分支名
可以切换到其他分支:
$ git checkout experimental
Switched to branch 'experimental'
切换到experimental
分支,切换完成后,先编辑里面的一个文件,再提交(commit)改动,最后切换回 “master”分支:
# 修改文件file1
$ echo "update" >> file1
# 查看当前状态
$ git status
# 添加并提交file1的修改
$ git add file1
$ git commit -m "update file1"
# 查看file1的内容
$ cat file1
test
update
# 切换到master分支
$ git checkout master
查看下file1
中的内容会发现刚才做的修改已经看不到了。因为刚才的修改时在experimental
分支下,现在切换回了master
分支,目录下的文件都是master
分支上的文件了。
现在可以在master
分支下再作一些不同的修改:
# 修改文件file2
$ echo "update again" >> file2
# 查看当前状态
$ git status
# 添加并提交file2的修改
$ git add file2
$ git commit -m "update file2 on master"
# 查看file2的内容
$ cat file2
test
update again
这时,两个分支就有了各自不同的修改,分支的内容都已经不同,如何将多个分支进行合并呢?
可以通过下面的git merge
命令来合并experimental
到主线分支master
:
# 切换到master分支
$ git checkout master
# 将experimental分支合并到master
$ git merge -m 'merge experimental branch' experimental
-m
参数仍然是需要填写合并的注释信息。
由于两个branch修改了两个不同的文件,所以合并时不会有冲突,执行上面的命令后合并就完成了。
如果有冲突,比如两个分支都改了一个文件file3,则合并时会失败。首先我们在master分支上修改file3文件并提交:
# 切换到master分支
$ git checkout master
# 修改file3文件
$ echo "master: update file3" >> file3
# 提交到master分支
$ git commit -a -m 'update file3 on master'
然后切换到experimental,修改file3并提交:
# 切换到experimental分支
$ git checkout experimental
# 修改file3文件
$ echo "experimental: update file3" >> file3
# 提交到experimental分支
$ git commit -a -m 'update file3 on experimental'
切换到master进行合并:
$ git checkout master
$ git merge experimental
Auto-merging file3
CONFLICT (content): Merge conflict in file3
Automatic merge failed; fix conflicts and then commit the result.
合并失败后先用git status
查看状态,会发现file3显示为both modified
,查看file3内容会发现:
$ cat file3
test
<<<<<<< HEAD
master: update file3
=======
experimental: update file3
>>>>>>> experimental
上面的内容也可以使用git diff
查看,先前已经提到git diff
不加参数可以显示未提交到缓存区中的修改内容。
可以看到冲突的内容都被添加到了file3中,我们使用vim编辑这个文件,去掉git自动产生标志冲突的<<<<<<
等符号后,根据需要只保留我们需要的内容后保存,然后使用git add file3
和git commit
命令来提交合并后的file3内容,这个过程是手动解决冲突的流程。
# 编辑冲突文件
$ vim file3
# 提交修改后的文件
$ git add file3
$ git commit -m 'merge file3'
当我们完成合并后,不再需要experimental
时,可以使用下面的命令删除:
$ git branch -d experimental
git branch -d
只能删除那些已经被当前分支的合并的分支. 如果你要强制删除某个分支的话就用git branch –D
如果你觉得你合并后的状态是一团乱麻,想把当前的修改都放弃,你可以用下面的命令回到合并之前的状态:
$ git reset --hard HEAD^
# 查看file3的内容,已经恢复到合并前的master上的文件内容
$ cat file3
还有一种需要特殊对待的情况,在前面没有提到。通常,一个合并会产生一个合并提交(commit), 把两个父分支里的每一行内容都合并进来。
但是,如果当前的分支和另一个分支没有内容上的差异,就是说当前分支的每一个提交(commit)都已经存在另一个分支里了,git 就会执行一个“快速向前"(fast forward)操作;git 不创建任何新的提交(commit),只是将当前分支指向合并进来的分支。
git log命令可以显示所有的提交(commit):
$ git log
如果提交的历史纪录很长,回车会逐步显示,输入q
可以退出。
git log
有很多选项,可以使用git help log
查看,例如下面的命令就是找出所有从"v2.5“开始在fs目录下的所有Makefile的修改:
$ git log v2.5.. Makefile fs/
Git会根据git log命令的参数,按时间顺序显示相关的提交(commit)。
如果用--stat选项使用'git log',它会显示在每个提交(commit)中哪些文件被修改了, 这些文件分别添加或删除了多少行内容,这个命令相当于打印详细的提交记录:
$ git log --stat
你可以按你的要求来格式化日志输出。--pretty
参数可以使用若干表现格式,如oneline
:
$ git log --pretty=oneline
或者你也可以使用 short
格式:
$ git log --pretty=short
你也可用medium
,full
,fuller
,email
或raw
。 如果这些格式不完全符合你的需求, 你也可以用--pretty=format
参数定义格式。
--graph
选项可以可视化你的提交图(commit graph),会用ASCII字符来画出一个很漂亮的提交历史(commit history)线:
$ git log --graph --pretty=oneline
日志记录可以按不同的顺序来显示。如果你要指定一个特定的顺序,可以为git log
命令添加顺序参数。
按默认情况,提交会按逆时间顺序显示,可以指定--topo-order
参数,让提交按拓扑顺序来显示(就是子提交在它们的父提交前显示):
$ git log --pretty=format:'%h : %s' --topo-order --graph
你也可以用 --reverse
参数来逆向显示所有提交日志。
本节讲解了几个基本命令: