前言

最近本人将一些代码放到了github上,顺便总结了一下git的用法;经过了各种百度,最终形成了以下这篇文章。

个人感觉追求效率的话,只看最后一条git常用命令即可。

前面的似乎有用,又似乎没用......

Git使用方法

  • 简介

Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。

Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。

  • 安装

Git 各平台安装包下载地址为:Git - Downloads

  • Git工作流程

一般工作流程如下:

1.克隆 Git 资源作为工作目录。

2.在克隆的资源上添加或修改文件。

3.如果其他人修改了,你可以更新资源。

4.在提交前查看修改。

5.提交修改。

6.在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。

下图展示了 Git 的工作流程:

  • Git 工作区、暂存区和版本库

工作区:就是你在电脑里能看到的目录。

暂存区:英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。

版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。

图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。

当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

当执行 "git rm --cached <file>" 命令时,会直接从暂存区删除文件,工作区则不做出改变。

当执行 "git checkout ." 或者 "git checkout -- <file>" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。

当执行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

  • Git基本操作

1.git init

(1) 使用当前目录做为git仓库:

git init

该命令执行完毕后会在当前目录生成一个.git目录。

(2) 使用指定目录做为git仓库:

git init newrepo

该命令执行完毕后会在newrepo下生成.git目录。

2.将文件纳入版本控制:

$ git add *.c

$ git add README

$ git commit -m '初始化项目版本'

以上命令将当前目录下以 .c 结尾及 README 文件提交到仓库中。

3.git clone

(1)比如,要克隆代码仓库 Grit,可以用下面的命令:

$ git clone git://github.com/schacon/grit.git

执行该命令后,会在当前目录下创建一个名为grit的目录,其中包含一个 .git 的目录,用于保存下载下来的所有版本记录。

(2)如果要自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:

$ git clone git://github.com/schacon/grit.git mygrit

Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。

4.git status

git status 以查看在你上次提交之后是否有修改。

使用 -s 参数,获得简短的结果输出。如果没加该参数会详细输出内容

5.git diff

执行git diff来查看执行 git status 的结果的详细信息。

git diff 命令显示已写入缓存与已修改但尚未写入缓存的改动的区别。git diff 有两个主要的应用场景。

尚未缓存的改动:git diff

查看已缓存的改动: git diff --cached

查看已缓存的与未缓存的所有改动:git diff HEAD

显示摘要而非整个 diff:git diff --stat以查看在你上次提交之后是否有修改。

6.git commit

使用 git add 命令将想要快照的内容写入缓存区, 而执行 git commit 将缓存区内容添加到仓库中。

Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步需要配置用户名和邮箱地址。

$ git config --global user.name 'runoob'

$ git config --global user.email test@runoob.com

接下来我们写入缓存,并提交对 hello.php 的所有改动。在首个例子中,我们使用 -m 选项以在命令行中提供提交注释。

$ git add hello.php

$ git commit -m '第一次版本提交'

如果你没有设置 -m 选项,Git 会尝试为你打开一个编辑器以填写提交信息。

如果你觉得 git add 提交缓存的流程太过繁琐,Git 也允许你用 -a 选项跳过这一步。如下:

git commit -am '修改 hello.php 文件'

7.git reset HEAD

git reset HEAD 命令用于取消已缓存的内容。

$ git add .

$ git reset HEAD hello.php

现在你执行 git commit,就不会提交hello.php了。

8.git rm

如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 Changes not staged for commit 的提示。

要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除,然后提交。可以用以下命令完成此项工作

git rm <file>

如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f

git rm -f <file>

如果把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,使用 --cached 选项即可

git rm --cached <file>

可以递归删除,即如果后面跟的是一个目录做为参数,则会递归删除整个目录中的所有子目录和文件:

git rm –r *

进入某个目录中,执行此语句,会删除该目录下的所有文件和子目录。

9.git mv

git mv 命令用于移动或重命名一个文件、目录、软连接。

然后对其重名:

$ git mv README  README.md

  • Git分支管理

1.基本命令

创建分支命令:

git branch (branchname)

切换分支命令:

git checkout (branchname)

当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的工作目录的内容, 所以多个分支不需要多个目录。

合并分支命令:

git merge

你可以多次合并到统一分支, 也可以选择在合并之后直接删除被并入的分支。

2.列出分支

列出分支基本命令:

git branch

没有参数时,git branch 会列出你在本地的分支。

当你执行 git init 的时候,默认情况下 Git 就会为你创建 master 分支。

用 git checkout (branch) 切换到我们要修改的分支。

也可以使用 git checkout -b (branchname) 命令来创建新分支并立即切换到该分支下,从而在该分支中操作。

3.删除分支

删除分支命令:

git branch -d (branchname)

4.分支合并

一旦某分支有了独立内容,你终究会希望将它合并回到你的主分支。 你可以使用以下命令将任何分支合并到当前分支中去:

git merge

例如:

git merge newtest

将 newtest 分支合并到主分支去,test.txt 文件被删除。

合并完后就可以删除分支(也可以不删):

$ git branch -d newtest

删除后, 就只剩下 master 分支了。

5.合并冲突

当分支中的文件发生了修改,并且主分支中同一个文件也发生了修改,此时将分支合并到主分支,就会发生冲突。

此时,需要手动修改这个文件:

$ vim runoob.php

$ cat runoob.php

<?php

echo 1;

echo 'runoob';

?>

之后,可以用 git add 要告诉 Git 文件冲突已经解决

$ git add runoob.php

  • Git查看提交历史

在使用 Git 提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,我们可以使用 git log 命令查看。

可以用 --oneline 选项来查看历史记录的简洁的版本。

$ git log --oneline

还可以用 --graph 选项,查看历史中什么时候出现了分支、合并。

也可以用 --reverse 参数来逆向显示所有日志。

$ git log --reverse --oneline

如果只想查找指定用户的提交日志可以使用命令:git log --author

$ git log --author=Linus --oneline -5

如果你要指定日期,可以执行几个选项:--since 和 --before,但是你也可以用 --until 和 --after。

$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges

  • Git标签

如果你达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以使用 git tag 给它打上标签。

比如说,我们想为我们的 runoob 项目发布一个"1.0"版本。 我们可以用 git tag -a v1.0 命令给最新一次提交打上(HEAD)"v1.0"的标签。

-a 选项意为"创建一个带注解的标签"。

$ git tag -a v1.0

当你执行 git tag -a 命令时,Git 会打开你的编辑器,让你写一句标签注解,就像你给提交写注解一样。

现在,当我们执行 git log --decorate 时,就可以看到我们的标签了

如果我们忘了给某个提交打标签,又将它发布了,我们可以给它追加标签。

例如,假设我们发布了提交 85fc7e7(上面实例最后一行),但是那时候忘了给它打标签。 我们现在也可以:

$ git tag -a v0.9 85fc7e7

如果我们要查看所有标签可以使用以下命令:

$ git tag

指定标签信息命令:

git tag -a <tagname> -m "runoob.com标签"

PGP签名标签命令:

git tag -s <tagname> -m "runoob.com标签"

  • Git 远程仓库(Github)

Git 并不像 SVN 那样有个中心服务器。

目前我们使用到的 Git 命令都是在本地执行,如果你想通过 Git 分享你的代码或者与其他开发人员合作。你就需要将数据放到一台其他开发人员能够连接的服务器上。

1.添加远程库

要添加一个新的远程仓库,可以指定一个简单的名字,以便将来引用,命令格式如下:

git remote add [shortname] [url]

本例以 Github 为例作为远程仓库,如果你没有 Github 可以在官网 https://github.com/注册。

由于你的本地 Git 仓库和 GitHub 仓库之间的传输是通过SSH加密的,所以我们需要配置验证信息:

使用以下命令生成 SSH Key:

$ ssh-keygen -t rsa -C "youremail@example.com"

后面的 your_email@youremail.com 改为你在 Github 上注册的邮箱,之后会要求确认路径和输入密码,我们这使用默认的一路回车就行。成功的话会在 ~/ 下生成 .ssh 文件夹,进去,打开 id_rsa.pub,复制里面的 key。

回到 github 上,进入 Account => Settings(账户配置)。

左边选择 SSH and GPG keys,然后点击 New SSH key 按钮,title 设置标题,可以随便填,粘贴在你电脑上生成的 key。

为了验证是否成功,输入以下命令:

$ ssh -T git@github.com

Hi tianqixin! You've successfully authenticated, but GitHub does not provide shell access.

以下命令说明我们已成功连上 Github。

之后登录后点击" New repository " 。

之后在在Repository name 填入 runoob-git-test(远程仓库名) ,其他保持默认设置,点击"Create repository"按钮,就成功地创建了一个新的Git仓库。

我们可以从这个仓库克隆出新的仓库,也可以把本地仓库的内容推送到GitHub仓库。

现在,我们根据 GitHub 的提示,在本地的仓库下运行命令:

$ mkdir runoob-git-test                     # 创建测试目录

$ cd runoob-git-test/                       # 进入测试目录

$ echo "# 菜鸟教程 Git 测试" >> README.md     # 创建 README.md 文件并写入内容

$ ls                                        # 查看目录下的文件

README

$ git init                                  # 初始化

$ git add README.md                         # 添加文件

$ git commit -m "添加 README.md 文件"        # 提交并备注信息

[master (root-commit) 0205aab] 添加 README.md 文件

 1 file changed, 1 insertion(+)

 create mode 100644 README.md

# 提交到 Github

$ git remote add origin git@github.com:tianqixin/runoob-git-test.git

$ git push -u origin master

以上命令请根据你在Github成功创建新仓库的地方复制,而不是根据我提供的命令,因为我们的Github用户名不一样,仓库名也不一样。

接下来我们返回 Github 创建的仓库,就可以看到文件已上传到 Github上。

2.查看当前的远程库

要查看当前配置有哪些远程仓库,可以用命令:

git remote

执行时加上 -v 参数,你还可以看到每个别名的实际链接地址。

$ git remote -v

3.提取远程仓库

Git 有两个命令用来提取远程仓库的更新。

(1)从远程仓库下载新分支与数据:

git fetch

该命令执行完后需要执行git merge 远程合并到你所在的分支。

(2)从远端仓库提取数据并尝试合并到当前分支:

git merge

该命令就是在执行 git fetch 之后紧接着执行 git merge 远程分支到你所在的任意分支。

例:

$ git fetch origin

$ git merge origin/master

4.推送到远程仓库

推送你的新分支与数据到某个远端仓库命令:

git push [alias] [branch]

以上命令将你的 [branch] 分支推送成为 [alias] 远程仓库上的 [branch] 分支,实例如下。

$ touch runoob-test.txt      # 添加文件

$ git add runoob-test.txt

$ git commit -m "添加到远程"

master 69e702d] 添加到远程

 1 file changed, 0 insertions(+), 0 deletions(-)

 create mode 100644 runoob-test.txt

$ git push origin master    # 推送到 Github

5.删除远程仓库

删除远程仓库你可以使用命令:

git remote rm [别名]

实例

# 添加仓库 origin2

$ git remote add origin2 git@github.com:tianqixin/runoob-git-test.git

# 删除仓库 origin2

$ git remote rm origin2

$ git remote -v

origin    git@github.com:tianqixin/runoob-git-test.git (fetch)

origin    git@github.com:tianqixin/runoob-git-test.git (push)

  • 命令行中github的用法

1.使用命令

ssh-keygen -t rsa -C "youremail@example.com"

参数为github邮箱;输入文件保存地址,输入github密码;之后生成pub文件

2.回到 github 上,进入 Account => Settings(账户配置),选择 SSH and GPG keys,然后点击 New SSH key 按钮,title 设置标题,可以随便填,粘贴在你电脑上生成的 pub文件的内容。

3.输入以下命令测试:ssh -T git@github.com;如果失败,则搜索.ssh文件夹(C:\Users\Admin\.ssh),将第一步生成的两个文件粘贴到此处,并重命名为id_rsa与id_rsa.pub

4.在github中点击New respository,之后在Repository name 填入 runoob-git-test(远程仓库名) ,其他保持默认设置,点击"Create repository"按钮,就成功地创建了一个新的Git仓库。

5.按照提示信息创建一个测试文件并上传到git仓库:

echo "# 菜鸟教程 Git 测试" >> README.md

git init

git add README.md

git commit -m "123"

git remote add origin https://github.com/BlackHoleSeventh/gitest.git

git push -u origin master

之后需要输入用户名与密码,之后就上传成功了。

6.将一个已有的项目上传到github:

(1) cd到已有项目的目录中,使用git init;命令初始化

(2) 使用git add * ;将所有项目添加到git

(3) 使用git commit -m 任意信息将添加后的文件提交

(4) 使用git remote add myStore https://github.com/UserName/storeName.git添加一个远程仓库地址;其中myStore是自己起的仓库名,对应后面的地址;使用git remote -v即可查看自己有哪些仓库地址。

(5) 使用git push -u myStore master将代码推送到远程仓库的master分支中,其中myStore是自己起的仓库名,master是分支名。(可以任意起,如果远程仓库没有这个分支,则会创建一个)

7.将一个github项目更新到本地:

(1) cd到目标目录中,使用git fetch myStore命令拉到本地(没有参数,从远程master拉到了本地master目录中);其中myStore是自己起的仓库名(对应url用)。

(2) 使用git merge myStore/master命令将内容同步。其中myStore是自己起的仓库名,master是同步到本地master分支。

8.将一个github项目下载到本地空文件夹:

(1) cd到目标空文件夹中,使用git clone https://github.com/UserName/storeName.git name命令,其中url为github仓库的网址,name为自己起的文件夹名,也可以不加,则会使用storeName为文件夹名。clone操作是一个从无到有的克隆操作,不需要git init初始化。

(2) 也可以使用git pull,相当于从远程仓库获取最新版本,然后再与本地分支merge(合并)。

举例:将远程主机origin的master分支拉取过来,与本地的branchtest分支合并。

$ git pull origin master:branchtest

(3) 以上的git pull操作也可以用git fetch来表示:

$ git fetch origin master:brantest

$ git merge brantest

将远程master分支下载到本地brantest分支;

将brantest分支合并入主分支master。

使用fetch可以先查看代码不同,再决定是否合并。

git fetch更新本地仓库的两种用法:

# 方法一

$ git fetch origin master                #从远程的origin仓库的master分支下载代码到本地的origin master

$ git log -p master.. origin/master      #比较本地的仓库和远程参考的区别

$ git merge origin/master                #把远程下载下来的代码合并到本地仓库,远程的和本地的合并

# 方法二

$ git fetch origin master:temp           #从远程的origin仓库的master分支下载到本地并新建一个分支temp

$ git diff temp                          #比较master分支和temp分支的不同

$ git merge temp                         #合并temp分支到master分支

$ git branch -d temp                     #删除temp

9.Git回滚:

(1) 使用git log --pretty=oneline查看历史版本

(2) 使用git reset --hard 9e4a2468e8ecb8d763b7e53549bd982c3370d00d回退到指定版本

10.git上传大文件:

(1) 在项目目录下,使用git lfs install命令

(2) 使用命令:git lfs track “* .gif” --这里的 “ *.gif "就是你要上传的大文件的路径

(3) 使用命令:git add .gitattributes

(4) 先提交:git commit -m "123";

(5) 先上传:git push -u orgin master

(6) 之后再上传大文件。注意,一定要先上传.gitattributes文件才可以!

11.git撤销add命令:

git reset HEAD //可以全部恢复未提交状态

git reset --hard HEAD //把全部更改的文件都恢复(小心使用,不然辛辛苦苦写的全没了)

  • Idea中git的用法

1.cd到指定目录,使用命令

git init

git add *

git commit -m msg

git remote add orgin https://github.com/UserName/UserStore.git

git push -u orgin master

将代码同步到远程仓库

2.或者使用

git clone git://github.com/UserName/UserStore.git

将代码下载到本地

3.使用idea打开项目,会出现提示是否要用git管理项目,选“yes”

4.或者,上方vcs菜单中有checkout from version control子菜单,其中可以设置git地址。

5.在右下角“Git:master”处,点击选择“New Branch”可以添加新分支

6.在右下角选择“check out”选择目标分支

7.上方有update按钮与commit按钮,commit按钮可以选择commit and push;之后会要求输入用户名密码,即可push到远程仓库。

8.下方“version control”中可以查看正在修改的文件,可以选择commit或revert。

9.上方vcs菜单中有git子菜单,可以选择revert、clone、fetch、pull、push等操作。

10.分支代码更新后,可以回到主分支,选择另一个分支的merge,即可将分支代码同步到主分支;主分支代码更新后,也可以先进入从分支,选择主分支的merge,即可将代码同步到当前分支。

11.当一个分支的代码push后,可以进入其它分支merge此分支的代码,如果此时merge其余分支的代码,则不会有反应,因为git只保存一个提交对象。

12.当两个以上从分支push后,主分支想merge其中一个分支,则会发生冲突,需要选择接受哪一个分支。

  • TortoiseGit的用法

1.安装

2.安装好后,右键可以发现TortoiseGit的相关菜单

3.选择git clone从仓库下载代码,或者选择git create repository here...创建.git文件夹

4.可以使用commit、push、revert操作代码

5.可以使用create branch创建分支,使用Switch/Checkout切换分支。

6.先进入目标分支,然后选择merge,再选择另一个分支,就可以将代码合并到目标分支上。

7.删除分支:点击“Switch/Checkout打开对话框,点击Switch to区域中Branch条目后面的更多按钮,打开分支列表对话框,右键点击要删除的分支,选择delete branch进行删除。

  • Git冲突与解决方法

1、git冲突的场景

情景一:多个分支代码合并到一个分支时;

情景二:多个分支向同一个远端分支推送代码时;

实际上,push操作即是将本地代码merge到远端库分支上。

关于push和pull其实就分别是用本地分支合并到远程分支 和 将远程分支合并到本地分支

所以这两个过程中也可能存在冲突。

git的合并中产生冲突的具体情况:

(1)两个分支中修改了同一个文件(不管什么地方)

(2)两个分支中修改了同一个文件的名称

两个分支中分别修改了不同文件中的部分,不会产生冲突,可以直接将两部分合并。

2、冲突解决方法

情景一:在当前分支上,直接修改冲突代码--->add--->commit。

情景二:在本地当前分支上,修改冲突代码--->add--->commit--->push

 注:借用vim或者IDE或者直接找到冲突文件,修改。

  • 个人总结:Git常用命令

--------------------------------------------

//git上传本地项目以及上传大文件

git init

git remote add orgin https://github.com/UserName/UserStore.git

git lfs install

git lfs track "*.*"

git add .gitattributes

git commit -m "LFS上传大文件"

git push -u orgin master

git add *

git commit -m "上传已存在项目"

git push -u orgin master

--------------------------------------------

//git从仓库下载项目(还有clone与pull,不过只用fetch也可以)

git init

git remote add orgin https://github.com/UserName/UserStore.git

git fetch orgin

git merge orgin/master

--------------------------------------------

//git查看提交历史

git log --pretty=oneline

--------------------------------------------

//git revert,生成一个新的提交来撤销某次提交,此次提交之前的commit都会被保留

git revert HEAD #撤销倒数第一次提交

git revert HEAD^ #撤销倒数第二次提交

git revert HEAD~2 #撤销倒数第三次提交

git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c61

--------------------------------------------

//git reset,回到某次提交,提交及之前的commit都会被保留,但是此次之后的修改都会被退回到暂存区,用法与revert类似

//git取消add操作

git reset HEAD

//只回退某个指定文件到指定版本

git reset a4e215234aa4927c85693dca7b68e9976948a35e MainActivity.java

--------------------------------------------

============================

Git用户名与邮箱配置方法(公司统计个人提交代码量用)

//git配置用户名
git config --global user.name "z"
//git配置邮箱
git config --global user.email z@sina.com

//git检查配置的用户名
git config user.name
//git检查配置的邮箱
git config user.email

//git查看其它配置
git config --list 

Git删除add的文件的方法

有时候新打开项目,git会自动把.idea文件夹中的文件add进去,但是这些文件是不应该commit的,更不应该add,看着很烦;

下面是把add的文件删除的方法(只从add记录中删除,文件本身还在):

#删除.idea中所有文件的add记录
git rm -rf --cached ./.idea


#删除某个文件的add记录
git rm -f --cached ./xxx.iml

解决Git报错:You have not concluded your merge (MERGE_HEAD exists).

这个问题是当时合并git代码时没有合并好,想重新合并时报了这个错;

可以执行下方的命令,撤销上次的合并,然后自己重新再合并一次。

git merge --abort
git reset --merge
git pull

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐