1. 安装 git
不同系统下 git 的安装
Mac上可以在终端上输入:
git --version
来查看git是否安装,以及当前git的版本号。
以下内容,均为在Mac电脑上使用为前提。git在Mac上的常用的图形化工具一般是:SourceTree 。 本文主要介绍git 的命令行模式, SourceTree 的使用,见下方参考资料中的 GUI for git|SourceTree|入门基础
2. 初次运行前 git的配置
当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址。 这样做很重要,因为每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改:
git config -- global user.name "chenxi"
git config -- global user.email chenxi@01game
如果使用了 --global 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用这些信息。
通过如下命令检查配置信息
git config --list
3. 获取git仓库
3.1 在现有目录中初始化仓库
如果你打算使用 Git 来对现有的项目进行管理,你只需要进入该项目目录并输入:
git init
该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪。
如果你是在一个已经存在文件的文件夹(而不是空文件夹)中初始化 Git 仓库来进行版本控制的话,你应该开始跟踪这些文件并提交。 你可通过 git add 命令来实现对指定文件的跟踪,然后执行 git commit 提交:
git add
git commit -m "提交信息"
3.2 从远端克隆一份已经存在的仓库
执行如下命令:
git clone /path/to/repository
git 工作流介绍:
你的本地仓库由git维护的三棵“树”组成。第一个是你的 工作目录,它持有实际文件; 第二个是 暂存区(Index) ,它像个缓存区域,临时保存你的改动;最后是 HEAD ,它指向你最后一次提交的结果
4.添加和提交
4.1 使用如下命令,把本地文件添加到暂存区。
git add filename
一次性提交所有的变化
git add -A
4.2 使用如下命令,提交实际改动部分:
git commit -m "代码提交信息"
现在,本地的改动已经提交到了HEAD,但是还没有到远端仓库。
5.推送
使用如下命令,提交到远端仓库
git push origin master
默认是master分支,当然你可以把master切换到任何想要推送的分支
当然也可以使用如下命令:
git push -u origin master
-u
告诉git记住这次push的参数,下次运行 git push
的时候,git就知道该怎么做了。
6.更新与合并
使用如下命令更新本地仓库到最新的改动:
git pull
他相当于 获取(fetch)
并且 合并(merge)
远端的改动
7. 替换本地改动
使用如下命令替换掉本地改动:
git checkout -- readme.txt
命令 git checkout -- readme.txt
意思就是,把 readme.txt
文件在工作区的修改全部撤销,这里有两种情况:
一种是
readme.txt
自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;一种是
readme.txt
已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit
或 git add
时的状态
注意此命令中的 --
非常重要, 如果没有,就变成了切换分支的命令了。
**假如你想丢弃你在本地的所有改动与提交,可以到服务器上获取最新版本历史,并将你本地主分支指向它:**
git fetch origin
git reset --hard origin/master
当然还可以使用 `git revert` 命令来撤销某次操作。此次操作之前和之后的` commit` 和`history`都会保留,并且把这次撤销作为一次最新的提交
git revert HEAD 撤销前一次 commit
git revert HEAD^ 撤销前前一次commit
git revert commit-id (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)撤销指定的版本,撤销也会作为一次提交进行保存。
git revert是提交一个新的版本,将需要revert的版本的内容再反向修改回去,版本会递增,不影响之前提交的内容
8.删除文件
在Git中,删除也是一个修改操作。例如先添加一个新文件test.txt 到git并提交:
git add test.txt
git commit -m "add test.txt"
一般情况下,我们通常在文件管理器中直接把文件删了,或者使用 rm
命令:
rm test.txt
这个时候,我们有两种选择,一是确实要从库版本中删除该文件,那就使用 git rm
命令:
git rm test.txt
git commit -m "remove test.txt"
git pull --rebase
git push origin master
第一条命令: 从库版本中删除test.txt
第二条命令: 提交信息
第三条命令:推送之前,先拉取信息,并且使用变基命令来代替合并
第四条命令:推送到远端仓库
另一种情况是,删错了,因为库版本里面还有,所以可以很轻松的把误删的文件恢复到最新版本:
git checkout -- test.txt
删除文件夹的操作类似:例如已经在git中添加了second文件夹,删除执行如下指令
git rm second -r
或者是强制删除second文件夹极其下所有的文件
git rm second -r -f
9.忽略文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式。
文件 .gitignore 的格式规范如下:
所有空行或者以 # 开头的行都会被 Git 忽略。
可以使用标准的 glob 模式匹配。
匹配模式可以以(/)开头防止递归。
匹配模式可以以(/)结尾指定目录。
要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
10. git分支
分支是用来将特性开发绝缘开来的。在你创建仓库的时候,master是默认的分支。在其他分支上进行开发,完成后再将它们合并到主分支上。
创建分支:
git branch testing
创建一个叫做“feature_x”的分支,并切换过去:
git checkout -b feature_x
切换回主分支:
git checkout master
再把新创建的分支删掉:
git branch -d feature_x
将分支推送到远端仓库,不然该分支就是不为他人所见的:
git push origin
查看每个分支的最后一次提交:
git branch -v
查看哪些分支已经合并到当前分支:
git branch --merged
分支前的 *
表示当前分支
查看所有包含未合并工作的分支:
git branch --no-merged
合并分支:
git merge
11. git 分支-变基
在 Git 中整合来自不同分支的修改主要有两种方法: merge
以及 rebase
。
整合分支最容易的方法是 merge
命令。 它会把两个分支的最新快照 以及二者最近的共同祖先进行三方合并,合并的结果是生成一个新的快照(并提交)。
其实,还有一种方法:可以提取 新建分支
中引入的补丁和修改, 然后在 master
分支的基础上再应用一次。 在git上,这种操作就叫做 变基
。 可以使用 rebase
命令将提交到某一分支上得所有修改都移至道另一分支上,就好像重新播放一样。如下所示:
git checkout experiment
git rebase master
它的原理是首先找到这两个分支(即当前分支 experiment
、 变基操作的目标基底分支 master
) 的最近共同祖先(假如叫做 c2
),然后对比当前分支相对于该祖先分支的历次提交,提取相应地修改并存为临时文件,然后将当前分支指向目标基底,最后以此将之前另存为临时文件的修改依序应用。
现在回到 master
分支上,进行一次快进合并。
git checkout master
git merge experiment
这两种整合方法的最终结果没有任何区别, 但是变基使得提交历史更加整洁。你在查看一个经过变基的分支的历史记录时会发现,尽管实际的开发工作是并行的,但是他们看上去就像是先后串行的一样,提交历史是一条直线没有分叉。
一般我们这么做的目的是为了确保在向远程分支推送时能保持提交历史的整洁——例如向某个别人维护的项目贡献代码时。 在这种情况下,你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到 origin/master 上,然后再向主项目提交修改。 这样的话,该项目的维护者就不再需要进行整合工作,只需要快进合并便可。
变基的风险
变基也并非完美无缺,要用它得遵循一条准则:
不要对在你的仓库外有副本的分支执行变基。
变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。如果有人依赖那些丢弃的提交,会产生问题。
如果没有分支的情况下,我们拉取数据的时候,最好还是按如下指令进行:
git pull --rebase
在我们使用图形化工具sourceTree 的时候,当我们拉取数据的时候,最好勾选上 用变基代替合并
这一选项。如下图所示
只要你把变基命令当作是在推送前清理提交使之整洁的工具,并且只在从未推送至共用仓库的提交上执行变基命令,你就不会有事。
更多变基相关知识,请戳这里
12. git 子模块
有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。
Git 通过子模块来解决这个问题。 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。
**12.1 将一个已存在的 Git 仓库添加为正在工作的仓库的子模块,以aonesdk仓库来举例 **
git submodule add [email protected]:core_developers/pub_protocols.git
默认情况下,子模块会将子项目放到一个与仓库同名的目录中,本例中是“protocols”。如果需要放在其他地方,可以在命令结尾添加一个不同的路径。
添加完,子模块之后,会生成一个.gitmodules文件。该文件保存了项目的URL和与已经大区的本地目录之间的映射. 可以使用如下命令来查看:
cat .gitmodules
12.2 克隆含有子模块的项目
使用 git clone /path/to/repository
来克隆项目时,默认会包含该子模块目录,但其中还没有任何文件。
必须使用 git submodule init
来初始化本地配置文件, 之后使用 git submodule update
从该项目中抓取所有数据并检出父项目中列出的合适的提交。
更简单的方式是,使用 --recursive
选项,它会自动初始化并更新仓库中的每一个子模块。例如使用如下命令:
git clone --recursive http://192.168.7.181/sdk_developers/aonesdk.git
12.3 在包含子模块的项目上工作
拉取上游修改
在项目中使用子模块的最简模型,就是只使用子项目并不时地获取更新,而并不在你的检出中进行任何更改。
如果想要在子模块中查看新工作,可以进入到子模块的目录中运行 git fetch
与 git merge
,合并上游分支来更新本地代码。
如果不想在子目录中手动抓取与合并,还有钟更容易的方式。运行 git submodule update --remote
, git 将会进入子模块然后抓取并更新。例如:
git submodule update --remote protocols
此命令默认会假定你想要更新并检出子模块仓库的 master 分支。
为了确保这不会发生,你可以让 Git 在推送到主项目前检查所有子模块是否已推送。 git push
命令接受可以设置为 “check” 或 “on-demand” 的 --recurse-submodules
参数。 如果任何提交的子模块改动没有推送那么 “check” 选项会直接使 push 操作失败。例如:
git push --recurse-submodules=check
如果子模块没有更新,会推送失败,并给出提示。简单的方法是进入每一个子模块中然后手动推送到远程仓库,确保他们能被外部访问到,之后再次尝试这次推送
另一个选项是使用 on-demand
值, 它会尝试为你这么做。例如:
git push --recurse-submodules=on-demand
合并子模块改动:
如果你其他人同时改动了一个子模块引用,那么可能会遇到一些问题。 也就是说,如果子模块的历史已经分叉并且在父项目中分别提交到了分叉的分支上,那么你需要做一些工作来修复它。
使用 git diff
命令来查看不同分支中的提交记录
一般的解决步骤如下:
- 首先解决冲突
- 然后返回到主项目目录中
- 再次检查SHA-A值
- 解决冲突的子模块记录
- 提交我们的合并
更多更改详细的子模块学习,请戳这里
13. git 其他命令
帮助命令
git help
查看当前文件状态
git status
查看提交历史
git log
查看不同
git diff
14. git 使用经验总结
14.1 每次使用git命令进行操作时,都需要输入用户名和密码
解决方法:
GitHub获得远程库时,有ssh方式和https方式。两个方式的url地址不同,认证方式也不同。使用ssh时保存密钥对以后可以不再输入帐号密码,而https却不能。所以如果想要不再输入帐号密码,一种方式就是在git clone的时候使用ssh方式,另一种方式就是去修改已有项目.git目录下的config文件中的url。更改为ssl的地址。
14.2 sourceTree 使用错误
新买的Mac使用sourceTree克隆代码的时候报错:
warning: templates not found /usr/local/git/share/git-core/templates
问题的原因: 意思是在Mac上找不到模板
解决方法: 在终端上面输入:
open /usr/local/
依次输入下列命令:
sudo mkdir /usr/local/git(这一条命令后面需要输入用户密码)
sudo mkdir /usr/local/git/share
sudo mkdir /usr/local/git/share/git-core
sudo mkdir /usr/local/git/share/git-core/templates
sudo chmod -R 755 /usr/local/git/share/git-core/templates
前四条创建目录,最后一条给修改目录添加权限. 注意 sudo 创建目录需要输入当前 Mac 用户的密码
** 14.3 克隆HTTP 错误 **
出现如下错误信息:
原因:代码太大,克隆不下来
解决办法: 配置clone的文件,分批次下载。 或者使用SSH 下载。
15. 参考资料
- git 维基百科介绍
- SourceTree 下载地址
- git 官网地址
- git 教程
- GUI for git|SourceTree|入门基础