Git 使用手册

2018-08-06  本文已影响157人  lovesosoi

Git

本文是根据扔物线大神的git手册和https://git-scm.com/book/zh/v2进行整理

1.什么是版本控制系统?

Git 是一个分布式版本控制系统,Version Control System - VCS

最简化的版本控制模型,是大多数主流文本编辑器都有的「撤销(Undo)」功能:你本来想删除一个字符,却在按删除键之前不小心选中了全文,结果一下子整篇文档都被删光了,没关系,按一下「撤销」(Ctrl + Z 或 ⌘ + Z 或 U 等等,具体和你的操作系统以及编辑器有关),删掉的文字就都回来了。这其实是文本编辑器帮你自动保存了之前的内容,当你按下「撤销」的时候,它就帮你把内容回退到上一个状态;同理,按一次是会退到上一个版本,按两次就是回退到上上一个版本。

写程序的时候同样也难免会遇到「写错」的情况,所以程序的 VCS,当然也会需要版本控制功能,这样当你发现「昨天有一行代码写错了」,你就不用凭着记忆把那段代码背出来,而只需要在 VCS 中选择撤回到昨天的那个版本。

2.版本控制系统种类

中央版本控制系统,分布式版本控制系统

中央式版本控制系统(Centralized VCS)
分布式的版本控制系统(Distributed VCS)

区别

类别 中央式版本控制系统 分布式版本控制系统
是否有本地仓库
是否有中央仓库
推送步骤 拉取中央版本到本地,合并本地版本,上传到中央服务器 拉取中央到本地仓库,合并中央版本和本地版本,上传到本地仓库,同步到中央仓库

3.git基本操作

安装

点击这里去下载个 Git ,安装到你的机器上。或者如果你喜欢用 Homebrew 或 apt 什么的来安装都好,总之,把它安装好。如果不会的话,请自行百度,“如何安装git",及”如何配置git环境“

装好以后,就可以正式开始上手 Git 了。

目录分析

.git --- 此目录为本地仓库,是隐藏文件
.gitignore --- git的忽略文件
LICENSE --- 协议文件不用管

clone

git clone git地址 (此命令是clone到当前目录地址)
git clone git地址 本地文件目录(此命令是clone到指定的本地文件目录)

举例:
git clone https://github.com/lvm0306/Android-ui-2018.git (该指令是拉取到本地的默认地址)
git clone https://github.com/lvm0306/Android-ui-2018.git /Users/lovesosoi/Documents/git_space/Android-ui-2018(该指令是将项目拉取到了/Users/lovesosoi/Documents/git_space/Android-ui-2018 )

github 中 创建时没有Readme,没有 LICENSE 的话,git不会自动创建 master 分支,如果有Readme和License时,git会自动创建master。

创建时自带master分支


image

创建时不带master分支


image

当push一个空项目时,没有master 分支的项目,git会自动创建一个master分支。


image

当Push 一个有master项目时,git 则会传到master上。


image

git辅助指令

git log
查看提交记录

image

git log -p
查看详细历史

git log --stat
查看简要统计

git status
查看本地仓库文件状态,红色是未添加,绿色是已添加,如果是本地服务器已经上传到github服务器,即本地文件与服务器文件一致的话,则显示如下文字

git show
查看具体提交的详细内容

git show commit_id
即:git show 5e68b0d8
查看某次提交的具体详情

git show commit_id xxx
即:git show 5e68b0d8 README.md
查看某次提交的README.md 的具体修改细节

git diff --staged
使用 git diff --staged 和 git diff --cached 可以显示暂存区和上一条提交之间的不同。换句话说,这条指令可以让你看到「如果你立即输入 git commit,你将会提交什么」,此两条语句的效果完全一致

Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

如果本地仓库的文件状态大于github服务器的状态的话,则会显示如下文字

Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

image

add

git add xxx
添加xxx文件
git add .
添加git目录下所有未添加过的文件

commit

git commit

:wq!

push

git push

git pull

冲突

push前要不pull的话,并且github服务器被他人提交过,此时是提交不成功的,会提示:如下信息


image

所以要养成好习惯,每次push前一定要pull

如果github 服务器被人提交过,并且改的文件和你改的文件一致,那么本地需要修改冲突即merge,与服务器冲突时会显示如下文字,并且告诉你需要merge的文件

image

通过vim 指令查看冲突文件具体内容,

<<<<<
服务器代码
=====
本地代码
>>>>>
image

分支

创建分支

git branch test

切换分支

git checkout test

创建分支同时并且切换

git checkout -b test

在分支添加文件,上传文件时 会提示

fatal: The current branch test has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin test

这是因为git本地新建一个分支后,必须要做远程分支关联。如果没有关联, git 会在下面的操作中提示你显示的添加关联

提交分支

git push origin test

合并分支

先切换到主分支,在进行分支合并

git checkout master
git merge test
git push
删除分支

git branch -d test//删除本都test分支
git push origin -d test//删除远程分支

删除注意

1.HEAD 指向的 branch 不能删除。如果要删除 HEAD 指向的 branch,需要先用 checkout 把 HEAD 指向其他地方。

查看所有分支

git branch -a

取回刚删除的分支
git reflog//找到branch1分支被删除前的commit c08de9a
git checkout c08de9a
git checkout -b branch1

Pull Request

提交分支后,创建一个pull request,可以让其他人查看,提交内容是否有问题,如果有问题可以继续commit,直到此次分支修改完成,点击Merge pull request

rebase(变基)与交互式变基

把你指定的 commit 以及它所在的 commit 串,以指定的目标 commit 为基础,依次重新提交一次。
换个解释:你可以提取在 分支 中引入的补丁和修改,然后在 master 的基础上应用一次。 在 Git 中,这种操作就叫做 变基。

$ git checkout test
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

$ git checkout master
$ git merge test

无论是通过变基,Merge,还是通过三方合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。 变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。

撤销操作

撤销最新的一次操作,此处分两种情况

1,提交了但是没有push,此时撤销最新一次本地仓库提交
2,提交了,push了,此时撤销服务器的最新一次提交

解决1:
主要语句git commit --amend
举例

vim README.md
git add .
git commit -m "1"
git log
//此时log 有一条提交信息为1的,但是此时后悔了,想修改上一条提交

vim README.md
git add .
git commmit --amend

此时进入与提交语句页面,单与平常不同的是,第一行是之前的提交信息,即“1”
我们将其修改成 “2”

git log

此时提交信息为1的那条记录已经没了

解决2:
如果提交的分支是自己控制的分支(即代码都是自己可控制的)
使用git push origin branch1 -f
先用上一个解决办法,将本地库修改为正确的(此时本地库为争取的),此时提交肯定会冲突的,但是这个冲突是已知的,所以不能按照常规push 操作,需要强制push
git push origin branch1 -f

如果提交的内容已经被合并到了master 上了怎么办,此时是不能强制push的,万一覆盖了别人的代码,就等着那人提到砍你吧。
此时的操作应该是
git revert HEAD^
上面这行代码就会增加一条新的 commit,它的内容和倒数第二个 commit 是相反的,从而和倒数第二个 commit 相互抵消,达到撤销的效果。

撤下以前不知道多少次之前的一次操作

主要通过 git rebase -i 某次commit
通过git log 找到自己的需要修改commit Sha1值及commit信息

可以通过 ^~ 来定位到需要修改的commit

说明:在 Git 中,有两个「偏移符号」: ^ 和 ~。
^ 的用法:在 commit 的后面加一个或多个 ^ 号,可以把 commit 往回偏移,偏移的数量是 ^ 的数量。例如:master^ 表示 master 指向的 commit 之前的那个 commit; HEAD^^ 表示 HEAD 所指向的 commit 往前数两个 commit。
~ 的用法:在 commit 的后面加上 ~ 号和一个数,可以把 commit 往回偏移,偏移的数量是 ~ 号后面的数。例如:HEAD~5 表示 HEAD 指向的 commit往前数 5 个 commit。...

eq:

git rebase -i HEAD^^ 是指倒数第二次的提交
git rebase -i 3571d777723f67
3571d777723f67 是倒数第二次的commit ShA1值

通过以上两种方式都能定位到你需要修改commit 上。
然后进入到提交界面,与之不同的是,最上边是

pick absdnm commit信息1
pick asdwqe commit信息2

将与之前记住的commit信息与之校对,找到相同的那一行,将pick 改为edit,然后保存。
会出现如下提示:证明此时rebase 已经停留在了你想修改的那一条commit上了

You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue

通过git commit --amend更正

Successfully rebased and updated refs/heads/test43.

最后将修改的commit 应用上去

git rebase --continue

删除操作

删除上一条的commit
git reset --hard HEAD^

HEAD^:表示恢复到HEAD上一条(^,~功能上一条有讲)
或者使用

git reset --hard 8b02128e

删除到8b02128e 这条commit 之前的所有commit

删除某一条操作

比如只删除倒数第二条的数据

git rebase -i HEAD^^

然后界面如下

pick de42fd0 ic  ---倒数第二条commit
pick 13fe8e3 add  ---倒数第一条comit

# Rebase 512dee3..13fe8e3 onto 512dee3 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
~

我们要删除倒数第二条commit,所以删除第一行就可以了
出现如下提示,说明操作成功了,可以通过git log 查看下 倒数第二条commit 是否已经被删除了

Successfully rebased and updated refs/heads/master.

分支部分合并到master

情景如下

1-2-3-4-5-6
    a-b-c-d

123456是master的commit
abcd是分支branch 的commit
1.现在需要将abcd 合并master

git rebase 第3个commit

2.现在需要将bcd合并master

git rebase --onto 第3个commit 第a个commit branch

stash

git stash
如果目前正在修改branch ,但是需要去master 改bug,而且很急,但是工作区内有内容,可以通过git stash将工作区暂存,再去 checkout master,去修改master。

git stash pop
master bug改好了,通过git stash pop将刚才存储的工作区的内内容取出来。

存储时如果有未add的内容,执行git stash -u,将未add的内容也一起存储了。

checkout

当前项目做到了3.0.0版本,突然有一天,老板要2.0.0的安装包,此时你突然发现,以前的你是个傻只,没有将2.0.0建分支,也没有留过2.0.0的代码,但是你每次提交时都有一个好习惯,提交时,写了提交内容,你顺着提交记录,找到了2.0.0的最后一次提交commit。
此时只需要执行git checkout commit_Sha1就会将该commit的代码检出来。
git checkout HEAD^^^^^^^^
git checkout master^7
以上都可以检出你需要的代码,只要能找到2.0.0的commit就可以,当然最好还是,每发一个版本,都建立相应的分支,这样以后操作也会方便不少。

reset

git reset --hard HEAD^
删除了最新的一次commit,如果当时commit 的工作区和暂存区有内容的,也会一并清除。这样并不是都满足我们的需求,我们强烈要求保留工作目录
git reset --soft HEAD^
soft会保留工作目录内容所带来的差异文件放进暂存区。
git reset HEAD^
不加参数是使用默认参数 --mixed保留工作目录,并清空暂存区

参数 效果
--hard 重置位置的同时,清空工作目录的所有改动;
--soft 重置位置的同时,保留工作目录和暂存区的内容,并把重置 HEAD 的位置所导致的新的文件差异放进暂存区。
--mixed(默认) 重置位置的同时,保留工作目录的内容,并清空暂存区。...

.gitignore

主要分为忽略某个具体文件,忽略某个文件夹下的所有文件,忽略某一类文件

以斜杠“/”开头表示目录;
以星号“*”通配多个字符;
以问号“?”通配单个字符
以方括号“[]”包含单个字符的匹配列表;
以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;

规则:fd1/*
说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;
规则:/fd1/*
说明:忽略根目录下的 /fd1/ 目录的全部内容;
规则:*.dex
说明:忽略所有.dex文件

上一篇下一篇

猜你喜欢

热点阅读