文章目录
- Git 概述
- 常用Git命令
- GitHub使用
- 多人协作
- Git 配置
Git 概述
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 各平台安装包下载地址为:http://git-scm.com/downloads
在 Windows 平台上安装 Git 同样轻松,有个叫做 msysGit 的项目提供了安装包,可以到 GitHub 的页面上下载 exe 安装文件并运行:
安装包下载地址:http://msysgit.github.io/
我们先来理解下Git 工作区、暂存区和版本库概念
工作区:就是你在电脑里能看到的目录。
暂存区:英文叫 stage, 或 index。一般存放在 “.git目录下” 下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。
常用Git命令
创建版本库(git init)
用 git init 在目录中创建新的 Git 仓库。 你可以在任何时候、任何目录中这么做,完全是本地化的。
在目录中执行 git init,就可以创建一个 Git 仓库了。
mkdir gitlearn
cd gitlearn
git init
可以看到在你的项目中生成了 .git 这个子目录。 这个目录是Git来跟踪管理版本库的.
克隆操作 ( git clone )
使用 git clone 拷贝一个 Git 仓库到本地,让自己能够查看该项目,或者进行修改。
如果你需要与他人合作一个项目,或者想要复制一个项目,看看代码,你就可以克隆那个项目。
git clone [url] //[url] 为你想要复制的项目地址
默认情况下,Git 会按照你提供的 URL 所指示的项目的名称创建你的本地项目目录。 通常就是该 URL 最后一个 / 之后的项目名称。如果你想要一个不一样的名字, 你可以在该命令后加上你想要的名称。
git clone https://github.com/lucoo01/woodcalculator.git simpleapp
更新数据 ( git fetch )
git fetch:从远程获取最新版本到本地,不会自动 merge
更新数据 ( git pull )
git pull:相当于是从远程获取最新版本并merge到本地
git pull
git pull origin master
git pull origin [分支名]
查看项目当前状态(git status)
git status 命令用于查看项目的当前状态。
git status 加 -s 参数表示查看的是简要信息
git status
git status -s
查看改动(git diff)
git diff 命令显示已写入缓存与已修改但尚未写入缓存的改动的区别
git diff //查看尚未缓存的改动
git diff --cached //查看已缓存的改动
git diff HEAD //查看已缓存的与未缓存的所有改动
git diff --stat //显示摘要而非整个diff
git status 显示你上次提交更新后的更改或者写入缓存的改动, 而 git diff 一行一行地显示这些改动具体是什么。
添加到暂存区(git add)
可以通过 git add 将文件添加到暂存区,作为下次提交的(部分或全部)内容。
git add [文件/文件夹]
其他使用方法:
git add .
在项目中,添加所有文件很普遍,我们可以使用 git add . 命令来添加当前项目的所有文件,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件
git add -u
仅监控已经被add的文件(即tracked file),他会将被修改的文件提交到暂存区。add -u 不会提交新文件(untracked file)。(git add --update的缩写)
git add -A
是上面两个功能的合集, 也就是说包括删除的文件也会被提交(git add --all的缩写)
向仓库提交代码(git commit)
使用 git add 命令将想要快照的内容写入缓存区, 而执行 git commit 将缓存区内容添加到仓库中。
Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步需要配置用户名和邮箱地址。
git config --global user.name 'myname'
git config --global user.email 111111111@qq.com
使用 -m 选项以在命令行中提供提交注释
git commit -m "update myfile"
如果你没有设置 -m 选项,Git 会尝试为你打开一个编辑器以填写提交信息。 如果 Git 在你对它的配置中找不到相关信息,默认(Linux)会打开 vim。
如果你觉得 git add 提交缓存的流程太过繁琐,Git 也允许你用 -a 选项跳过这一步。
git commit -am "update myfile"
推送分支(git push)
我们想将本地分支推送到远程库,可以使用 git push 命令,在推送时,要指定本地分支, 这样,Git 就会把该分支推送到远程库对应的远程分支上:
git push
git push origin master
git push origin [分支名]
取消已缓存的内容 ( git reset HEAD )
HEAD指向的版本就是当前版本
简而言之,执行 git reset HEAD 以取消之前 git add 添加。
git reset HEAD -- [文件]
取消git add的所有内容:
git reset HEAD
撤销修改 ( git checkout – file)
把 该文件 在工作区的修改全部撤销:
git checkout -- [文件名]
如果 文件 修改后还没有被放到暂存区,现在,撤销修改就是用版本库的版本覆盖当前的文件。
如果 文件 已经添加到暂存区后,又作了修改,现在,撤销修改就是将暂存区中的文件版本覆盖当前的文件。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
删除文件(git rm)
git rm 从版本库中删除文件
git rm [文件]
如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f
git rm -f [文件]
如果把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,本地又需要使用, 只是不希望这个文件被版本控制,使用 --cached 选项即可
git rm --cached [文件]
我们可以使用 -r 参数进行递归删除, 即如果后面跟的是一个目录做为参数,则会递归删除整个目录中的所有子目录和文件
git rm –r [文件夹]
如果只是简单地从工作区中手工删除文件,运行 git status 时就会在 Changes not staged for commit 的提示。
这时你有两个选择,一是确实要从版本库中删除该文件,那就用命令 git rm 删掉,并且 git commit
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本
git checkout -- [文件]
git checkout – 其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
移动、重命名(git mv)
git mv 命令用于移动或重命名一个文件、目录、软连接。
git mv myfile.c newfile.c //重命名
git mv myfile.c ../myfile.c
历史记录(git log)
git log命令显示从最近到最远的提交日志:
git log
如果嫌 git log 输出信息太多,看得眼花缭乱,可以加上–pretty=oneline参数:
git log --pretty=oneline
版本回退(git reset)
要把当前版本回退到上一个版本,可以使用git reset命令:
git reset --hard HEAD^ //回退到上一个版本
在 Git 中,用 HEAD 表示当前版本,上一个版本就是 HEAD^,上上一个版本就是 HEAD^^,往上100个版本写成HEAD~100
版本回退到早期版本后,当前的这个版本不会从版本库中删除
git reset --hard 后也可以指定 commit id 切到指定版本:
git reset --hard [commit id]
如果需要找到commit id,Git 提供了一个命令git reflog用来记录你的每一次命令,找到commit对应语句前的id即可
git reflog
git reflog显示整个本地仓储的 commit, 包括所有 branch 的 commit, 甚至包括已经撤销的 commit, 只要 HEAD 发生了变化, 就会在 reflog 里面看得到.
分支基础命令
列出分支 :
git branch
创建分支命令:
git branch [分支名]
切换分支命令:
git checkout [分支名]
当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的工作目录的内容, 所以多个分支不需要多个目录。
创建新分支并立即切换到该分支下:
git checkout -b [分支名]
合并分支命令:
git merge [分支名] //在master中执行
你可以多次合并到统一分支, 也可以选择在合并之后直接删除被并入的分支。
删除分支:
git branch -d [分支名]
标签操作
查看所有的标签:
git tag
创建标签 ( git tag)
创建标签,只需切换到要打标签的分支上,使用 git tag 标签名 就可以创建一个新标签:
git branch [分支名]
git tag [标签名]
标签是默认打在最新提交的 commit id 上的
也可以直接再某个 commit id 上打标签:
git tag [标签名] [commit id]
也可以创建带有说明的标签(-a指定标签名,-m指定说明文字):
git tag -a [标签名] -m "This is v0.9" [commit id]
查看标签信息:
git show [标签名]
删除打错的标签:
从本地删除:
git tag -d [标签名]
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除,然后,从远程删除。
git push origin :refs/tags/[标签名]
推送标签到远程
推送某个标签到远程:
git push origin [标签名]
也可以,一次性推送全部尚未推送到远程的本地标签:
git push origin --tags
GitHub使用
gitHub 是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名 gitHub
添加远程仓库
我们使用 gitHub 创建一个在线仓库, 然后将其与本地仓库关联.
我们在 Repository name 填写 gitlearn 其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库
现在,这个仓库还是空的, GitHub 告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到 GitHub 仓库。
我们将本地已有仓库与之关联:
git remote add origin https://github.com/lucoo01/gitlearn.git
然后,我们把本地库的所有内容推送到远程库上:
git push -u origin master
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,如果当前分支与多个主机存在追踪关系,
使用 -u 参数指定一个默认主机,这样后面就可以不加任何参数使用 git push
查看远程库信息
可以用 git remote 查看远程库的信息
加参数 -v 可以显示更详细的信息:
git remote
git remote -v
多人协作
解决冲突
两个分支中修改同一文件
比如, 在两个分支中修改了同一个文件的同一行代码,在合并的时候就会发生冲突.
① 使用 git status 可以告诉我们存在冲突文件和文件名
② 直接查看文件内容,Git 用 <<<<<<<,=======,>>>>>>> 标记出不同分支的内容
③ 修改后保存,提交
git add .
git commit -m "conflict fixed"
④ 使用带参数的 git log 也可以看到合并的情况:
git log --graph --pretty=oneline --abbrev-commit
同一分支上修改同一文件
假设你在 dev 分支上对 入口文件(比如:index.php) 进行修改, 而你的队友恰巧也改了这个文件,并且在你前面推送到远程 dev 分支上.
这时你直接向 dev 推送修改,就会失败, Git 会提示我们先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突(如果有冲突的话),再推送:
git pull
如果你没有指定关联 dev 分支与远程 origin/dev 分支的链接, git pull 会失败,这时要先设置下dev和origin/dev的链接:
git branch --set-upstream dev origin/dev
然后再 git pull 就可以了
如果 pull 下来,提示有冲突可以参照之前的解决冲突,提交,再 push 就可以了
分支管理策略
通常 Git 在合并分支的时候会用 Fast forward 模式, 这样删除分支后, 也会丢掉分支信息.
我们在合并分支时可以使用 --no-ff 参数,强制禁用 Fastforward 模式, 这样 Git 在合并时会生成一个新的 commit(提交), 然后我们就可以在历史分支上看出分支信息.
git merge --no-ff -m "merge with no-ff" [分支名]
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master 分支应该是非常稳定的,也就是仅用来发布新版本,平时不要直接在上面开发;
你可以和你团队成员在 dev 上开发, 每个人都有自己的分支, 然后时不时往 dev 分支上合并, 也就是说 dev 分支时不稳定的, 等到要发布版本的时候, 再将 dev 往 master 上合并就可以了
Git 配置
Git 提供了一个叫做 git config 的工具,专门用来配置或读取相应的工作环境变量。
这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:
/etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。
当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。
在 Windows 系统上,Git 会找寻用户主目录下的 .gitconfig 文件。主目录即 $HOME 变量指定的目录,一般都是 C:\Documents and Settings$USER。
此外,Git 还会尝试找寻 /etc/gitconfig 文件,只不过看当初 Git 装在什么目录,就以此作为根目录来定位。
如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。
如果要在某个特定的项目中使用其他名字或者邮件,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里
查看配置信息
检查已有的配置信息:
git config --list
有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。
这些配置我们也可以在 ~/.gitconfig 或 /etc/gitconfig 看到
忽略特殊文件
有时你必须把某些文件放入 Git 工作目录中, 又不能将其提交, 比如:存储了数据库密码的配置文件.
我们只需在 Git 工作区的根目录下创建一个名为 .gitignore 的文件, 写入过滤规则就行了.
.gitignore 文件不需要从头写,GitHub 已经为我们准备了各种配置文件,只需根据需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
忽略文件的原则是:
① 忽略操作系统自动生成的文件,比如缩略图等;
② 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如 Java 编译产生的 .class 文件;
③ 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
例如:
# Compiled class file
*.class