Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 与常用的版本控制工具 CVS, SVN 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
Git 提供了一个叫做 git config 的工具,专门用来配置或读取相应的工作环境变量。
设置用户名和邮箱,配置的用户名和邮件地址将在版本库提交时作为提交者的用户名和邮件地址。
git config --global user.name "hyn"
git config --global user.email "[email protected]"
如果用 --global选项,那么更改的配置文件就是位于你用户主目录下的那个配置,以后你所有的项目都会默认使用这里配置的用户信息。
如果要在某个特定的项目中使用其他名字或者邮箱,只要在对应的项目目录下去掉--global选项重新配置或者在对应的项目目录下把--global 换成--local即可,新的设定保存在当前项目的 .git/config 文件里。
可通过alias去修改git命令的别名
git status
是用来查看文件修改的命令,可以用git st 代替git pull
是用来拉取远程仓库代码的命令,可以用git pl 代替git push
是用来将本地修改推送到远程仓库的命令,可以用git ps 代替 查看整个配置信息:git config --local --lis
查找某个变量的设置:git config --local user.name
工作区:你电脑里项目的目录。
暂存区:英文叫stage,一般存放在”git目录”下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
工作区、暂存区和版本库之间的关系.png
图中左侧为工作区,右侧为版本库。在版本库中标记为 stage的区域是暂存区,标记为master的是项目的master分支。
图中我们可以看出此时HEAD实际是指向 master 分支的一个游标。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
当对工作区修改的文件执行git add
命令时,暂存区的目录树被更新即把工作区的修改添加到暂存区;当执行提交操作git commit
时,暂存区的目录树写到版本库中,master 分支会做相应的更新。即把暂存区的内容提交到当前分支
当执行git reset HEAD
命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 git rm --cached
命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行git checkout .
或者git checkout --
命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行git checkout HEAD .
或者git checkout HEAD
命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
版本库又名仓库,英文名repository,可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
使用 git init
命令来初始化一个 Git 仓库, 在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。
git init
git init 目录地址
使用 git clone
从现有的远程仓库中拷贝项目
git clone 仓库地址
git clone 仓库地址 目录地址
创建一个空的Git存储库或重新初始化一个现有的存储库。
git init [-q | --quiet] [--bare] [--template=]
[--separate-git-dir ]
[--shared[=]] [directory]
$ mkdir demo
$ cd demo
$ git init
Initialized empty Git repository in /Users/huangyangneng/Documents/workspace/git/demo/.git/
克隆一个远程仓库到本地目录。
git branch -r
查看),并从克隆检出的存储库作为当前活动分支的初始分支。将修改过的文件添加到缓存区中
git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p]
[--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]
[--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--renormalize]
[--chmod=(+|-)x] [--] […]
git commit
命令之前,必须使用git add
命令将任何新的或修改的文件添加到暂存区中。git add
命令时添加指定修改的内容; 如果希望随后的更改包含在下一个提交中,那么必须再次运行git add
将新的内容添加到暂存区中。git add
命令不会添加忽略的文件。 如果在命令行上显式指定了任何忽略的文件,git add
命令都将失败,并显示一个忽略的文件列表。由Git执行的目录递归或文件名遍历所导致的忽略文件将被默认忽略。 git add
命令可以用-f(force)选项添加被忽略的文件。查看当前仓库的状态
用来显示已写入缓存与已修改但尚未写入缓存的改动的区别。此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
git diff [options] [] [--] […]
git diff [options] --cached [] [--] […]
git diff [options] [--] […]
git diff [options]
git diff [options] [--no-index] [--]
显示工作树和索引或树之间的变化,索引和树之间的变化,两棵树之间的变化,两个blob对象之间的变化,或者磁盘上两个文件之间的变化。
git diff
git diff id1 id2
git diff branch1 branch2
git diff --staged
git diff --cached
git diff HEAD
git diff --stat
将缓存区内容添加到仓库中
git commit [-a | --interactive | --patch] [-s] [-v] [-u] [--amend]
[--dry-run] [(-c | -C | --fixup | --squash) ]
[-F | -m ] [--reset-author] [--allow-empty]
[--allow-empty-message] [--no-verify] [-e] [--author=]
[--date=] [--cleanup=] [--[no-]status]
[-i | -o] [-S[]] [--] […]
git commit
命令将暂存区的当前内容与描述更改的用户和日志消息一起存储在新的提交中。
要添加的内容可以通过以下几种方式指定:
在使用git commit
命令之前,通过使用git add
将工作区的内容添加到暂存区;
通过使用带有-a
选项的git commit
命令来添加从所有已知文件(即所有已经在暂存区中列出的文件),并自动从工作树中删除执行过“git rm
”的文件;
通过使用git rm
从工作树和暂存区中删除文件,再次使用git commit
命令;
通过将文件作为参数列出到git commit
命令(不使用--interactive
或--patch
选项),在这种情况下,提交将忽略暂存区中分段的更改,而是记录列出的文件的当前内容;
通过使用--interactive
或--patch
选项与git commit
命令一起确定除了暂存区中的内容之外哪些文件应该是提交的一部分,然后才能完成操作。
查看历史提交记录
git log [] [] [[\--] …]
该命令采用适用于git rev-list
命令的选项来控制显示的内容以及适用于git diff- *
命令的选项来控制每个提交的更改是如何显示的。
git log
git log --oneline
git log --no-merges
git log --merges
git log g--oneline --graph
git log --reverse --oneline
git log --author=huangyangneng --oneline
git log -3
git log commitId
--since,--affter
):git log --oneline --after={2018-04-18}
git log --oneline --before={1.day.ago}
用于将当前HEAD复位到指定状态。一般用于撤消之前的一些操作。
git reset [-q] [] [--] …
git reset (--patch | -p) [] [--] […]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] []
在第一和第二种形式中,将条目从
git reset [--hard|soft|mixed|merge|keep] [
:将当前的分支重设(reset)到指定的
git status
所示。当提交了之后,又发现代码没有提交完整,或者想重新编辑一下提交的信息,可执行git reset --soft HEAD^,让工作目录还跟reset之前一样,不作任何改变。git reset HEAD
git reset --hard HEAD^
git reset --hard HEAD^^
git reset --hard HEAD~N
git reset --hard
可以查看所有分支的所有操作记录(包括提交、回退、已删除的提交操作记录等)。
git reflog
git reflog
除了能查看所有提交记录外,还能查看会退,已删除等的操作记录。git reflog
每行记录都由版本号(commit id SHA),HEAD值和操作描述三部分组成。版本号在第一列,HEAD值在第二列,操作描述信息在第三列。当我们会退出错时,想回到某个新版本,就可以用git reflog
查看对应的commitId,然后进行会退。
git reflog
git reflog -n
--since,--affter
):git reflog --after={2018-04-18}
git reflog --before={1.day.ago}
用于从另一个存储库或本地分支获取并集成(整合)。git pull
命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并。
git pull [options] [ […]]
将远程存储库中的更改合并到当前分支中。在默认模式下,git pull
是git fetch
后跟git merge FETCH_HEAD
的缩写。更准确地说,git pull
使用给定的参数运行git fetch
,并调用git merge
将检索到的分支头合并到当前分支中。 如果使用--rebase
,它运行是git rebase
而不是git merge
。
$ git pull https://github.com/huangyangneng/demo.git master:master
Already up-to-date.
用于将本地分支的更新,推送到远程仓库。
git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=]
[--repo=] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
[-u | --set-upstream] [--push-option=]
[--[no-]signed|--signed=(true|false|if-asked)]
[--force-with-lease[=[:]]]
[--no-verify] [ […]]
使用本地引用更新远程引用,同时发送完成给定引用所需的对象。可以在每次推入存储库时,通过在那里设置挂钩触发一些事件。当命令行不指定使用
git push origin master
git push origin
git push
git push
:git push -u origin master
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。 在很多版本控制系统中,这是一个略微低效的过程——常常需要完全创建一个源代码目录的副本。对于大项目来说,这样的过程会耗费很多时间。
Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。
当我们用git init
初始化一个仓库时,此时git会默认帮我们创建一个主分支,即master分支。以及一个指向master分支的HEAD指针。一开始,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:
每次提交,master分支都会向前移动一步,HEAD始终指向master。这样,随着你不断提交,master分支的线也越来越长。
但我们创建一个新的分支并切换到新分支时,比如branchtest,此时git会新建一个可移动的指针,叫做branchtest,指向master相同的位置,再把HEAD指向branchtest,就表示当前分支在branchtest上:
从上面我们可以看出,git创建分支是很快的,因为就创建了一个新的指针。切换分支也是很快的,因为就把HEAD指针指到对应的分支上面。
然后我们在新的分支上修改提交,branchtest指针就向前移动,而master分支位置不变。
当我们在branchtest上面的工作做完后,就可以把branchtest分支合并到master分支了。git分支合并也很快,只需要把master指向当前的提交就完成了合并。
当我们把branchtest分支合并到master分支后,如果不需要branchtest分支了,我们就可以删除掉branchtest分支了,git删除分支就是把branchtest指针删除掉。
用于列出,创建或删除分支。
如果给出了--list
或者如果没有非选项参数,则列出现有的分支; 当前分支将以星号突出显示。 选项-r
导致远程跟踪分支被列出,而选项-a
显示本地和远程分支。 如果给出了一个--list
; 否则命令被解释为分支创建。
git branch or git branch --list
git branch
git checkout
git branch -a
git branch -m or -M
git branch -d or -D
git branch -r -d origin/
and git push origin :
用于切换分支或恢复工作树文件。
更新工作树中的文件以匹配索引或指定树中的版本。如果没有给出路径,git checkout
还会更新HEAD,将指定的分支设置为当前分支。
用于将两个或两个以上的分支合并一起。
将命名约定的更改合并到当前分支中。这个命令被git pull 合并来自另一个存储库的更改,并且可以手工使用以将更改从一个分支合并到另一个分支。
git merge
git merge --no-commit
git merge -m "message"
git log --graph --pretty=oneline --abbrev-commit
分支合并图.png
用于运行合并冲突解决工具来解决合并冲突。
git mergetool [--tool=] [-y | --[no-]prompt] […]
git mergetool
命令用于运行合并冲突解决工具来解决合并冲突。使用git mergetool
运行合并实用程序来解决合并冲突。它通常在git合并后运行。
如果给出一个或多个
参数,则将运行合并工具程序来解决每个文件的差异(跳过那些没有冲突的文件)。 指定目录将包括该路径中的所有未解析文件。 如果没有指定
名称,git mergetool
将在具有合并冲突的每个文件上运行合并工具程序。
mergetool命令工具.png
用于将更改储藏在脏工作目录中。
当要记录工作目录和索引的当前状态,但想要返回到干净的工作目录时,则使用git stash
。 该命令保存本地修改,并恢复工作目录以匹配HEAD提交。
这个命令所储藏的修改可以使用git stash list
列出,使用git stash show
进行检查,并使用git stash apply
恢复(可能在不同的提交之上)。调用没有任何参数的git stash
相当于git stash save
。 默认情况下,储藏列表为“分支名称上的WIP”,但您可以在创建一个消息时在命令行上给出更具描述性的消息。
git stash
git stash list
git stash apply(恢复)
and git stash drop(删除stash内容)
or git stash pop(恢复并删除stash内容)
用于创建,列出,删除或验证使用GPG签名的标签对象。同大多数 VCS 一样,Git 也可以对某一时间点上的版本打上标签。在发布某个软件版本(比如 v1.0 等等)的时候,经常这么做。
在refs/tags/中添加标签引用,除此之外还可以提供了-d/-l/-v
来删除,列出或验证标签。
tag 用于创建一个标签用于在开发阶段,某个阶段的完成,创建一个版本,在开发中都会使用到, 可以创建一个tag来指向软件开发中的一个关键时期,比如版本号更新的时候可以建一个version1.0, version1.2之类的标签,这样在以后回顾的时候会比较方便。除非指定-f选项,否则不能创建已经存在的标签。
如果传递了-a
,-s
或-u
中的一个,该命令将创建一个标签对象,并且需要一个标签消息。 除非-m
或-F
,否则将启动一个编辑器,供用户输入标签消息。
git tag
or git tag -a -m "标签说明"
or git tag
git tag
or git tag -l (列出指定的标签)
git tag -d