git详细使用及加入GitHub
1. Git的概述:
什么是Git?
--> 是用C语言开发的分布式版本控制系统。
--> 版本控制系统可以保留一个文件集合的历史记录,并能回滚文件集合到另一个状态(历史记录状态)。另一个状态可以是不同的文件,也可以是不同的文件内容。->举个例子,你可以将文件集合转换到两天之前的状态,或者你可以在生产代码和实验性质的代码之间进行切换。文件集合往往被称作是“源代码”。在一个分布版本控制系统中,每个人都有一份完整的源代码(包括源代码所有的历史记录信息),而且可以对这个本地的数据进行操作。分布版本控制系统不需要一个集中式的代码仓库。
使用Git的功能:
当你对本地的源代码进行了修改,你可以标注它们和下一个版本相关(将他们加入到stage的暂存区中 -- add
),然后提交到分支的本地仓库中去( commit
)。git 保存了所有的版本信息,所以可以转换源代码到任何的历史版本。你可以对本地的仓库进行代码的提交,然后与其他的远程或本地仓库进行同步。你可以使用 git 来进行仓库的克隆(clone),完整的复制一个已有的远程仓库。仓库的所有者可以进行push操作(推送变更到别处仓库)或pull操作(从别处仓库拉取变更)来同步变更。
2. Git的安装
在终端输入: git 。可以查看是否安装了Git.如果已经安装了Git,可通过在终端输入:"gitk"就启动了,打开图形工具,用来辅助管理Git;可以查看日志、注释、分支等信息。
>>方法1: 通过安装Homebrew,然后在安装Git。
第一步:打开终端,在终端输入如下命令安装Homebrew;
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
然后-输入密码,“return”,"brew help"一步步在终端中操作;安装Homebrew。
第二步:Homebrew安装好之后,就可以通过brew安装 Git了
brew install git
>>方法2: 直接去Git官网下载Git安装。 ttp://git-scm.com/downloads/
>>方法3:可以使用Xcode的集成环境进行安装git。
3. Git的重要术语:
git重要术语介绍4. 使用git (即本地操作)
通常使用git创建版本库又叫仓库。英文名 repository
, 可以简单理解成一个目录,这个目录里面的所有文件都可以被 git 管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
> 4.1 添加入文件或进行某些代码更改操作,通过git先操作 add
到仓库暂存区,然后在 commit
到该分支的本地仓库。
下面是从新建文件夹 --> 初始化git仓库 --> 添加新建文件 实现git功能 :
第一步:在合适的地方创建一个目录。(不一定需要在空目录下创建Git仓库,选择已有东西的目录也是可以的)
$ cd 拖入某个文件夹即可进入这个目录
$ mkdir firstgit -- 新建firstgit文件夹
$ cd firstgit -- 进入firstgit文件夹
第二步:用 git init 命令将这个目录变成可以使用git管理的仓库。
$ git init
//这样空的仓库,就建立好了,可以发现当前目录下多了一个 `.git` 的文件夹(.git默认为隐藏文件夹,需要开启显示隐藏文件夹功能),这个文件夹中是Git用来跟踪管理版本库的,千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。 //终端执行 ls -a/ls -ah 会发现目录里多.git文件(隐藏文件),这个就是git用来跟踪管理的文件。
第三步:在这个目录下创建个文件,并输入一些内容。
$ vi readme.txt
然后回车就可以进入刚刚创建的文件中;在键盘上敲击 i 键 进入编辑状态;输入完成后通过 esc键 退出编辑; 输入 “:wq” 进行保存
** 在进行接下来的步骤之前可以先查看某个仓库缓存区的状态以及相关文件:git status **
第四步:也同样可以把外部文件拖入刚刚创建的仓库,然后在加入到暂存区和仓库中区。用命令git add告诉Git,把文件添加到仓库
$ git add readme.txt/git add ./git add *.txt
//add: 将修改从工作区(就是电脑能看到的目录)提交到stage(或index)的暂存区;这时查看git status 看到添加文件是绿色还未commite
第五步:用命令git commit把文件提交到版本库
$ git commit -m "第一次提交"
//commit:将修改从stage(或index)的暂存区提交到 master 分支的版本库中。
*至此我们已经成功地添加并提交了一个文件到本地仓库。为什么会有add、commit呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件。如:$git add file1 $git add file2 $git commit -m"2file"
第六步: 如果该本地仓库链接了 `remote`远程仓库并且也在本地添加了远程仓库的 `remote`地址 接下来可以把本地仓库传到github/gitlab上去,在此之前可能需要设置 `username`和 `email`,因为github/gitlab每次commit都会记录他们。
** 设置本地git中所有git仓库 uers.name/user.email:
$ git config --global user.name "your name" //给自己起个用户名
$ git config --global user.email "your_email@youremail.com" //填写自己的邮箱
** 设置当前git仓库的 `user.name` + `user.email`
$ git config --user.name "your name" //此用户名可以和push的仓库对应。
$ git config --user.email "your_email@youremail.com" //填写remote仓库地址邮箱--以便可以做github/gitlab 做相应的配置。
> 4.2 在仓库中的文件被提交修改
-
当修改了仓库中的某个文件中的内容时,先使用
git status
查看状态显示绿色的文件已修改的状态,出现modified: ...
并且显各个文件为红色显示等。 -
接着可以使用命令:
git diff HEAD -- ...
查看修改的内容(查看的是工作区与版本库最新版本区别) -
然后使用命令
git add .
加入到stage(或index)的暂存区,然后git commit -m "仓库修改本次commit内容记录"
提交到当前分支的本地仓库。显示提交完成后,可使用git status
查看是否提交完成,是否文件没有add或者commit。
> 4.3 撤销各种场景的修改
-
场景1:当你改乱了
工作区
某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- "this file"
-
场景2:当你不但改乱了
工作区
某个文件的内容,还添加到了暂存区
时,想丢弃修改,分两步,第一步用命令git reset HEAD "this file"
,就回到了场景1,然后第二步按场景1操作。 -
场景3:已经提交了不合适的修改到
版本库
时,想要撤销本次提交,使用版本回退命令:git reset --hard HEAD^ --向前一个版本 /区分于使用版本号回退版本
> 4.4 版本回退
-
使用
git reflog--简便历史记录
命令查看commit历史,以便确定回退到哪一个版本。 当然还有另一个查看commit提交历史命令:git log--详细commit历史记录
(如果嫌输出信息太多,可以加上--pretty=oneline
参数后缀可以 即git log --pretty=oneline/git log --online
) -
现在可以通过
git log
可以看到commit_id(版本号)
。git必须知道当前版本是哪个版本,在Git中,用HEAD
表示当前版本,上一个版本就是:HEAD^
,上上一个版本就是:HEAD^^
,当然往上100个版本写100个^比较容易数不过来,所以写成:HEAD~100
。 -
现在就是要把当前版本回退到
commit_id
的某一个版本去,就可以使用命令:git reset --hard HEAD^^(一个^代表向前一个版本)
,这时就已经回退到之前修改的那个版本了。还有一个命令:git reset HEAD^
这个与版本回退不同这是重置,这是的操作是重置版本库工作区不变。 -
不过这时
git log
可以发现回退到当前版本的所有之前的提交历史已经消失了,如果回退操作出错了可以在未关闭的当前终端窗口找到之前的版本的commit_id(版本号)
,然后使用命令 git reset --hard xxx(xxx版本号的前几位左右作为区分,git会自动寻找)。Git的版本回退速度非常快,因为Git在内部有个指向当前版本的 HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从新指向。如果见过git效果图这种操作理解和效果就比较深刻了。 -
在
4
中如果需要回到未来的某个版本就需要之前的版本号如果已经关闭当前终端窗口了,就看不到未来的版本号了,但是可以使用命令git reflog
用于记录每一次命令就可以在一次回到未来的某个版本。
总结:HEAD
指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令: git reset --hard commit_id
穿梭前,用 git reflog / git log
可以查看提交历史,以便确定要回退到本地仓库的哪个版本,通过版本号 commit_id
确定。
要重返未来,用 git reflog
查看commit操作命令历史,以便确定要回到未来的哪个版本。
> 4.5 删除文件
你通常直接在文件管理器中把没用的文件删了,或者用rm命令删了
现在你有两个选择:
- 一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit;
- 另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
git checkout -- test.txt
,git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以实现“一键还原”。
总结:命令 git rm
用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
> 4.6 分支的使用
创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。但git的分支是与众不同的,无论创建、切换和删除分支,git可以在很短的时间内就能完成!无论你的版本库是1个文件还是1万个文件。
在git的版本回退里,每次提交,git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在git里,这个分支叫主分支,即 master分支
。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支
一开始的时候,master分支是一条线,git 用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:
HEAD
↘
master
↘
OO→ OO→ OO
每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长
HEAD
↘
master
↘
OO→ OO→ OO→ OO
当我们创建新的分支,例如 dev 时,git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上;git创建一个分支很快,因为除了增加一个dev指针,改变 HEAD 的指向,工作区的文件都没有任何变化!
master
↘
OO→ OO→ OO
↑
dev
↖
HEAD
不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:
master
↘
OO→ OO→ OO→ OO
↑
dev
↖
HEAD
假如我们在dev上的工作完成了,就可以把dev合并到master上。git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并.所以git合并分支会很快!就改改指针,工作区内容也不变!
master
↘
OO→ OO→ OO→ OO
↑
dev
↖
HEAD
合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:
HEAD
↘
master
↘
OO→ OO→ OO→ OO
>> 分支的实际运用:
a. 我们创建dev分支并同步切换到dev分支(二者同步执行)
$ git checkout -b dev
Switched to a new branch 'dev'
/*
* git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
* $ git branch dev
* $ git checkout dev
* Switched to branch 'dev'
*/
b. 然后,用 git branch
命令查看当前分支,git branch命令会列出所有分支,当前分支前面会标一个 *号
。
$ git branch
* dev
master
c. 然后,我们就可以在 dev分支
上正常提交,比如对xxx.txt
做个修改.
$ git add xxx.txt
$ git commit -m "branch test"
d. 现在,dev分支的工作完成,我们就可以切换回master分支,在主分支上以便后面的合并。注: 若dev当前分支有未提交内容则切换会失败提示先commit。
$ git checkout master
Switched to branch 'master'
e. 切换回 master分支
后,再查看一个 xxx.txt
文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变;现在,我们把dev分支的工作成果合并到master分支上;当git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。也可以用 git log --graph
命令可以看到分支合并图
$ git merge dev //git merge命令用于合并指定分支到当前分支。合并后,再master分支查看xxx.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。
f. 合并完成后,就可以放心地删除dev分支了(在没有把某个分支的内容合并之前,若执行删除某个分支,会进行提示,让你进行合并)
$ git branch -d dev
Deleted branch dev (was fec145a).
//删除后,查看branch,就只剩下master分支了:
//$ git branch
// * master
//g. 如果合并分支时,没有使用“Fast forward模式”,而禁用Fast forward,加上了"--no--ff"参数合并,则可以在最后查看分支历史
$ git merge --no--ff -m "merge with no--ff" dev
$ git log --graph --pretty=oneline --abbrev-commit
> 4.7 可以创建Bug分支修复Bug或增加feature分支来增加新的功能。
> 4.8 忽略特殊文件
有些时候,你必须把某些文件放到git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件等等,每次git status都会显示Untracked files ...解决方法:在git工作区的根目录下创建一个特殊的 .gitignore文件
,然后把要忽略的文件名填进去,git就会自动忽略这些文件。不需要从头写 .gitignore
文件,在使用GitHub中已经为我们准备了各种配置文件,只需要组合一下就可以使用了
忽略文件的原则是:
*忽略操作系统自动生成的文件,比如缩略图等;
*忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
*忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件
最后一步就是把 .gitignore
也提交到git,就完成了!当然检验.gitignore的标准是git status
命令是不是说working directory clean;你想添加一个文件到git,但发现添加不了,原因是这个文件被.gitignore忽略了;同样也可以强制添加到git。
//忽略编译产生的等文件或目录
# Windows: //#表示注释
Thumbs.db
ehthumbs.db
Desktop.ini
# My configurations: //这是自己定义的文件的配置
db.ini
deploy_key_rsa
//如果需要所有其它文件或版本库,使用.gitignore,则需使用 git config 命令配置git
$ git config -global ...
//文件被.gitignore忽略了,如果确实想添加该文件,可以用-f强制添加到Git
$ git add -f App.class
//或者你发现,可能是.gitignore写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore命令检查
$ git check-ignore -v App.class
.gitignore:3:*.class App.class
5. 将git的本地仓库提交到github远程仓库(远程操作.也可以搭建一个git服务器)
github网站
就是提供 git仓库 托管服务的,所以,只要注册一个GitHub账号,就可以免费获得Git远程仓库。
github网站在2018年被微软收购后,后又推出最多三人的免费git私人仓库(以前不付钱是没有私人仓库全部都是public )
由于git的本地仓库和GitHub之间的仓库是通过SSH加密的,所以还需要进行一些操作:
>> 5.1 创建SSH Key
在用户主目录下,看看有没有.ssh
目录,如果有,再看看这个目录下有没有 id-rsa
和 id-rsa.pub
这两个文件,如果已经有了,可直接跳到下一步;如果没有,打开Shell(Windows下打开git Bash),即iMac终端。同样也可以在终端中输入:ssh,来查看是否有 SSH Key
。
>> 创建 SSH Key
步骤:
*1.终端输入:ssh-keygen -t rsa -C xxxxx@xxxxx.com//注册GitHub时的邮箱就可以了。
//Generating public/private rsa key pair生成了公共/私有密钥对。(在终端输入“whereis ssh”可查看ssh位置)
2.要查看 “ssh”,需要在终端输入允许查看隐藏的文件(defaults write com.apple.finder AppleShowAllFiles -bool true)->/users.../.ssh
3.查看我的 public key:$cat ~/.ssh/id_rsa.pub
4.登陆GitHub,打开“Settings”,然后,点“SSH and GPG Keys”,点“New SSH Key”;填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容。点“Add Key”,你就应该看到已经添加的Key。其中可能还需要输入GitHub的密码;
5. 为了验证是否成功:$ ssh -T git@github.com.如果第一次进行连接就会提示“Are you sure you want to continue connecting(yes/no)”,输入yes看到提示,可能会需要输入ssh设置的密码,然后就表示成功连接上GitHub了
--回到github,刷新网页就可以看到钥匙旁的灰色小圆点变绿
>> 5.2 在GitHub上创建仓库
登陆GitHub,然后,在右上角找到“New repository”按钮,创建一个新的仓库。
在Repository name填入你需要保存的仓库名字,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库。
>> 5.3 在本地的仓库下(cd+拖入仓库文件)运行命令,以便连接GitHub远程仓库:
$ git remote add origin git@github.com:xxxxxx/xxxxxx.git
//origin是默认的远程主机名;git@github.com:ghn/repository.git,ghn是我的GitHub的名称,repository是要上传的GitHub的仓库名称。通过ssh连接,不要使用https,点击:Clone or download即可以出现地址。
可能出现的错误:在执行上面的命令时,错误提示:fatal:remote origin already exists
解决办法: $ git remote rm origin
然后在执行:$ git remote add origin git@github.com:xxxx/xxxx.git
使用下面的命令推送本地仓库至远程仓库/从远程仓库pull,获取远程仓库的文件到本地仓库:
(最后实在不行,不管什么问题可以执行强制推送:git push -u origin +mastr)
$ git push -u origin master/$ git pull origin master //这里的-u参数作为第一次提交使用,作用是把本地master分支和远程master分支关联起来,以后就可以直接使用:git push origin master命令即可直接push
而且一般会先pull在push,为了防止往GitHub上提交东西的时候,会因为远程上有东西更新了但是本地仓库没有更新而造成提交失败。
可能出现的错误:
1.error:failed to push some refs to.......
解决办法:$ git pull origin master // 先把远程服务器github上面的文件拉下来,再push 上去。 2.fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.
解决办法:出现这个问题是因为,没有在github账号添加SSH key
3.如果pull报错fatal: refusing to merge unrelated histories;
解决办法:则可以命令:git pull origin master ----allow-unrelated-histories
6.GitHub使用:从GitHub上Clone、更新和多人进行协作开发
6.1 克隆远程仓库
如果本地没有远程仓库的项目,想从远程仓库克隆一个仓库到本地应该怎么做呢?
- 只需要用
cd+ ... 命令
切换到想要存放项目的路径,然后直接执行git clone +#远程版本库地址#
命令就行了,注意命令后面跟的是项目的URL地址。项目在GitHub上的SSH和HTTPS地址均测试成功。
git clone
和 git pull
的区别 (后面的介绍git pull和git fetch的区别)
-
git clone
:从远程服务器克隆一个一模一样的版本库到本地,复制的是整个版本库,叫做clone.(clone是将一个库复制到你的本地某个目录中,是一个本地从无到有的过程)
命令: git clone +#远程版本库地址# +#本地目录名#
(需要制定不同的目录名,可以将目录名作为git clone 命令的第二个参数,这样就可以实现clone到本地的远程版本库的目录名可以自己改名,可与远程版本库不同)
-
git pull
:从远程服务器获取到一个branch分支
或者是master默认主分支
的更新到本地,并更新本地库,叫做pull.(pull是指同步一个在你本地有版本的库内容时更新的部分或者是分支内容到你的本地库)
命令: git pull +#远程版本库地址(origin)# +#远程分支(next)#:#本地分支(master)#
如果远程分支是与当前分支合并,则冒号后面的部分可以省略 git pull origin 远程分支(next或者默认分支master)
相当于: git fetch origin+fit merge origin/next
.
如果 pull 报错 fatal : refusing to merge unrelated histories;则可以命令:git pull origin master ----allow-unrelated-histories
关于git的本地与远程之间的分支之间建立追踪关系:其中有一点,git会自动在本地分支和远程分支之间,建立一种追踪关系。如在git clone的时候,所有本地分支默认与远程的同名分支建立了一种追踪关系即本地的master分支自动追踪"origin/master"分支。同样git可以手动建立追踪git branch --set-upstream master origin/next --->指定master分之追踪到origin/next。
6.2 同步远程服务器更新即分支更新(pull VS fetch)
即本地仓库同步远程仓库,但获取远程服务器更新的方式有两种,分别是 fetch
和 pull
,二者有差别。但是获取的远程仓库只是一个分支或者是默认分支(master).
fetch
:仅仅只是从远处服务器获取到最新版本到本地,假如你不去合并(merge)的话,本地工作空间是不会发生变化的!
pull
:是一步到位的,或者说:pull = fetch + merge
在实际使用中fetch更加安全,在merge(合并)之前可以查看更新情况,git status
查看,在决定是否进行合并。
6.3 在Github上进行多人协作开发(两种方式)
在GitHub进行多人协作开发时,有两种方式,
-
一种是几个开发者使用几个Github账号,一个是管理者,其它开发者进行"fork"的自己github账号,然后各个开发者push代码到自己的github账户中,然后pull request 管理者;
-
第二种是:全部开发者使用一个github账号,把每个开发者的电脑的ssh密钥加入到github账号中通过验证,每个开发者都是管理者。
a. 现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH Key添加到同一个GitHub账号中)
$ git clone git@github.com:GDaYao/Project-iOS.git
b. 现在,你的小伙伴要在dev分支上开发,就必须创建远程 origin的dev分支
到本地,于是他用这个命令创建本地dev分支
$ git checkout -b dev origin/dev
现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程
$ git commit -m "add /usr/bin/env"
$ git push origin dev
//向origin/dev分支推送了他的提交
总结:
1. 首先,可以试图用git push origin branch-name推送自己的修改;
2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;//如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name
3. 如果合并有冲突,则解决冲突,并在本地提交;
4. 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功
6.4 标签管理
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照
。tag就是一个让人容易记住的有意义的名字,它跟某个 commit_id
绑在一起。所以在不仅仅可以使用 commit_id
进行版本回退,标签管理更加方便。
标签使用:
*命令git tag <name>用于新建一个标签,默认为HEAD,也可以指定一个commit_id;
*git tag -a <tagname> -m "blablabla..."可以指定标签信息;
*git tag -s <tagname> -m "blablabla..."可以用PGP签名标签;
*命令git tag可以查看所有标签。
首先,切换到需要打标签的分支上
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'
然后,敲命令 git tag <name>
就可以打一个新标签
$ git tag v1.0
//可以用命令git tag查看所有标签
$ git tag
v1.0
要对 add merge
这次提交打标签,它对应的 commit_id是6224937
,敲入命令
$ git tag v0.9 6224937
再用命令git tag查看标签
标签不是按时间顺序列出,而是按字母排序的。可以用 git show <tagname>
查看标签信息,包括所有这个版本的很多内容。
$ git show v0.9
还可以创建带有说明的标签,用 -a指定标签名,-m指定说明文字
$ git tag -a v0.1 -m "version 0.1 released" 3628164
还可以通过 -s用私钥签名一个标签
$ git tag -s v0.2 -m "signed version 0.2 released" fec145a
当然还可以使用标签进行版本回退,比每次操作 commit_id
更加方便(同版本回退的方法):
$ git reset --hard v0.1(即某个版本)实现回到之前的版本/未来版本。
操作标签
$ git push origin <tagname>可以推送一个本地标签;
$ git push origin --tags可以推送全部未推送过的本地标签;
$ git tag -d <tagname>可以删除一个本地标签;
$ git push origin :refs/tags/<tagname>可以删除一个远程标签
7. 常用 git
命令清单:-- 可查看使用
几个专用名词译名:
Workspace:工作区
Index / Stage:暂存区
Repository:仓库区(或本地仓库)
Remote:远程仓库
1,新建代码库
# 在当前目录新建一个Git代码库
$ git init
# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]
# 下载一个项目和它的整个代码历史
$ git clone [url]
2,配置
Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)
# 显示当前的Git配置
$ git config --list
# 编辑Git配置文件
$ git config -e [--global]
# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"
3.增加/删除文件
# 添加指定文件到暂存区
$ git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
$ git add [dir]
# 添加当前目录的所有文件到暂存区
$ git add .
# 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
$ git add -p
# 删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1] [file2] ...
# 停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]
# 改名文件,并且将这个改名放入暂存区
$ git mv [file-original] [file-renamed]
4.?代码提交
# 提交暂存区到仓库区
$ git commit -m [message]
# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]
# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a
# 提交时显示所有diff信息
$ git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]
# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...
5. 分支的使用(Git鼓励大量使用分支)
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name> //这一步操作之前要进行分支切换以便确定合并到某分支
通常,合并分支时,如果可能,Git会用Fast forward模式即“快进模式”,也就是直接把master指向某分支的当前提交,所以合并速度非常快。但这种模式下,删除分支后,会丢掉分支信息。
合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
git merge --no-ff -m "merge with no-ff" dev
git log --graph --pretty=oneline --abbrev//查看分支历史
删除分支:git branch -d <name>
推送分支至远程仓库(这里master是git默认的主分支)
git push origin master
推送其他分支到远程仓库(dev是本地的其它分支)
git push origin dev
git branch --set-upstream dev origin/dev //指定本地dev分支与远程origin/dev分支的链接
6.标签
# 列出所有tag
$ git tag
# 新建一个tag在当前commit
$ git tag [tag]
# 新建一个tag在指定commit
$ git tag [tag] [commit]
# 删除本地tag
$ git tag -d [tag]
# 删除远程tag
$ git push origin :refs/tags/[tagName]
# 查看tag信息
$ git show [tag]
# 提交指定tag
$ git push [remote] [tag]
# 提交所有tag
$ git push [remote] --tags
# 新建一个分支,指向某个tag
$ git checkout -b [branch] [tag]
7. 查看信息
# 显示有变更的文件
$ git status
# 显示当前分支的版本历史
$ git log
# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat
# 搜索提交历史,根据关键词
$ git log -S [keyword]
# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s
# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature
# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]
# 显示指定文件相关的每一次diff
$ git log -p [file]
# 显示过去5次提交
$ git log -5 --pretty --oneline
# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]
# 显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个commit的差异
$ git diff --cached [file]
# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD
# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]
# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"
# 显示某次提交的元数据和内容变化
$ git show [commit]
# 显示某次提交发生变化的文件
$ git show --name-only [commit]
# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]
# 显示当前分支的最近几次提交
$ git reflog
8. 远程同步
# 下载远程仓库的所有变动
$ git fetch [remote]
# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ git remote show [remote]
# 增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]
# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]
# 上传本地指定分支到远程仓库
$ git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force
# 推送所有分支到远程仓库
$ git push [remote] --all
9. 撤销
# 恢复暂存区的指定文件到工作区
$ git checkout [file]
# 恢复某个commit的指定文件到暂存区和工作区
$ git checkout [commit] [file]
# 恢复暂存区的所有文件到工作区
$ git checkout .
# 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
$ git reset [file]
# 重置暂存区与工作区,与上一次commit保持一致
$ git reset --hard
# 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
$ git reset [commit]
# 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
$ git reset --hard [commit]
# 重置当前HEAD为指定commit,但保持暂存区和工作区不变
$ git reset --keep [commit]
# 新建一个commit,用来撤销指定commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]
# 暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop
10. 其它
# 生成一个可供发布的压缩包
$ git archive
在终端中的输入git命令:
git //确定电脑安装了git
git status //查看暂缓区的状态
git log/git log --pretty=oneline//可以查看提交历史,以便确定要回退到哪个版本。
git reflog //查看命令历史,以便确定要回到未来的哪个版本。
git reset --hard (版本号) //HEAD指向的版本就是当前版本,因此Git允许我们在版本的历史之间穿梭,使用此命令
git diff HEAD --...//工作区与版本库中最新版本的差别
git checkout -- file //放弃对工作区当前文件的修改,让这个文件回到最近一次git commit或git add时的状态
git reset hard file//可以把暂存区的修改撤销掉(unstage),重新放回工作区
git remote //查看远程库的信息
git remote -v //显示更详细的信息,显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址
8.git和GitHub的其它使用
8.1 如何为开源项目贡献代码
在GitHub上可以Clone别人的开源项目,在看别人代码的时候,你觉得作者有某些地方写得不好,写错,或者你有更好的想法,你在本地修改后,想把修改push推送到开源项目上,但是你不是项目的拥有着和参与者,是无法推送更改的!!
-
第一种方法:是让作者把你加为写作者,添加协作者流程:点击仓库的Settings-->Collaborators然后输入想添加的人的用户名或者邮箱,点击添加即可。
-
第二种方法:1).点击Fork按钮,把这个项目fork到自己的账号下,然后Clone到本地,然后做你想做的修改,commit提交.2).然后push到自己账号里的GitHub仓库,然后打开那个别人的开源项目,点击 Pull requests ,然后新建一个pull request,接着设置自己的仓库为源仓库,设置源分支,目标仓库与目标分支,然后还有pull request的标题和描述信息,填写完毕后,确定。3).这个时候开源项目的作者就会收到一个pull request的请求,由他来进行审核,作者审查完代码觉得没问题的话,他可以点击一下merge按钮即可将这个pull request合并到自己的项目中,假如作者发现了你代码中还有些bug,他可以通过Pull Request跟你说明,要修复了xxBUG才允许合并,那么你再修改下BUG,提交,更改后的提交会进入Pull Request,然后作者再审核这样!
8.2 在 Xcode
中使用 git
以及远程提交
在使用Xcode创建每个工程时,就已经显示了是否使用 git 来创建一个仓库,并且已经是初始化这个仓库了。Create Git Repository On Mac
就已经提示是否初始化创建为git仓库。如果勾选了就可以像使用普通git仓库一样,使用add,commit,push,pull而且可以直接在Xcode中操作。
9. gitLab更改ssh 可以加入和创建
git使用还可参考: Git的教程可以参考“廖雪峰的Git教程”</font>
9.git便捷使用
常用:
git ps (上传)
git ss (查看状态)
git aa (提交)
git ci -m“ ” (进一步提交)
git co -b dev (创建dev分支)
git ps origin dev
git br -a (列出分支)
//
Git便捷实用:
co = checkout
**ss = status -s
**ps = push
ci = commit -a
br = branch
st = status
**pl = pull
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
ft = fetch
di = diff
last = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -1
unstage = reset HEAD
mg = merge --no-ff
dt = difftool
aa = add .
theirs = checkout --theirs .
their = checkout --theirs --
ours = checkout --ours .
our = checkout --ours --
git 项目配置
注意: 所有的配置如果需要生效只有在配置更改信息后的下次变更时才会生效。
下面是git config相关的各个操作命令:
查看全局的 git配置,git cofnig 命令(在~/.gitconfig目录文件中存储的git global信息)
$ git config --global --edit (直接修改文件即可修改git全局配置的相关信息)
若需要直接从终端查看 user.name/user.email
$ git config --global user.name // 查看global user name
$ git config --global user.email // 查看global user eamil
查看或配置当前项目git 的相关信息(包括user.name+user.email+Author)
$ git show //查看当前项目的相关信息
$ git config user.name //查看当前项目的user name
$ git config user.email //查看当前项目的user email
$ git config user.name "GDayao" // 更改当前项目的 user name
$ git config user.email "xxxx@xx.com" // 更改当前项目的 user email ==> 注意这里的邮箱若和github/gitlab的注册邮箱相同则在提交历史中会显示头像否则为github默认头像
当前项目的config配置Author信息可以和全局配的config信息不相同。所以在全局的config没有配置的情况下,也可以配置当前项目的某些信息内容。
git 子模块
子模块的初步使用
对于子模块的理解使用,为什么使用子模块?什么时候使用子模块?最简单的理解,如果有多人合作或者直接使用了另一个项目/库,但是这个项目又需要调用主模块的某些内容,即使用 子模块
。(使用静态库或者动态库不能产生此种功能的情况下)
使用远程地址 添加子模块:
git submodule add <git://github.com/xxx.git>/本地git仓库路径也可
添加 submodule 成功后,会在主目录中生成一个 `.gitmodules`文件,里面存储了子模块的信息。
当然一个主工程中可以生成和添加多个子模块使用
在子模块添加完成后,可通过终端 cd
再次进入子模块内容,其他操作等同于一个git仓库,只不过这个 主工程不同的是项目工程中有两个git仓库需要维护和更新 add
/commit
带有子模块的项目拉取
克隆拉取带有子模块的项目
git clone git://github.com/xxx.git
而后 cd
进入主工程项目进行相关操作
git submodule init // 初始化你的本地配置文件
git submodule update // 从子工程中拉取项目更新添加数据
再次注意所有的子模块操作 => cd进入子模块进行等同git仓库操作
删除子模块
使用如下步骤命令操作:
$ git submodule deinit <xxx> // clear directory xxx,
$ git rm <xxx> // 直接删除这个子模块的所有文件,包括子模块的配置文件