Git 使用经验

缘起

一直想写一篇博文,记录我在使用git时遇到的问题以及解决办法。由于项目忙,偶尔的记录不连续,不成系统。今天有时间记录下来,方便自己以后查看。

git 简介及其优势

简单来说,git是类似csv, svn一类的版本控制工具,不过它是分布式的。

总结一下它的优点:

  • 适合分布式开发,强调个体。
  • 公共服务器压力和数据量都不会太大。
  • 速度快、灵活。
  • 任意两个开发者之间可以很容易的解决冲突。
  • 离线工作。

难道它没有缺点么?有的:

  • 代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息。
  • 部分童鞋反应比较难学

gitlab是神马?github又是神马?

说到git, 经常听到的一个词莫过于github, github是一个网站,它提供Git仓库托管服务,用户可以在上面创建各种git仓库,同时,它提供一个web界面,使得用户方便管理自己的项目。

但用户托管私有项目时需要付费,这时,你可以使用 gitlab 创建属于自己的 github。

GitLab是一个开源的版本管理系统,实现一个自托管的Git项目仓库,也可通过Web界面进行访问公开的或者私人项目。

git 一般工作流程

git是分布式版本控制系统,其最大的优势是,每个开发者拥有存相同的代码拷贝。

实际项目开发中,通常需要创建一个远程仓库,这个远程仓库有点类似SVN中央服务器,项目开发中所有的代码都统一提交到该远程仓库中,这方便代码的统一管理。

这个远程仓库通常由gitlab 或者 github托管。

如何新建版本库(仓库)?

首先,你在gilab 或者 github 上新建一个远程仓库(new repository);

创建完成后,会给出该远程仓库的地址:例如git@github.com:xxx/test1.git

然后再在本地创建仓库:

echo "# test" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:xxx/test1.git
git push -u origin master

注意,当运行最后一条命令时,可能提示错误:

The authenticity of host 'github.com (192.30.252.129)' can't be established.

RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added 'github.com,192.30.252.129' (RSA) to the list of known hosts.

Permission denied (publickey).

fatal: Could not read from remote repository.

Please make sure you have the correct access rights

and the repository exists.

不要慌,这是因为git使用ssh进行通信,本地主机向远程主机推送文件时,需要告诉对方自己的ssh publickey.

  • 首先,本地创建ssh-key
ssh-keygen -t rsa -C "example@foxmail.com"
  • 然后拷贝~/.ssh/id_rsa.pub中的公开密钥到github('edit profile' -> 'SSH and GPG keys')

    重新提交后出现下面提示方为成功。

$ git push -u origin master

Counting objects: 3, done.

Writing objects: 100% (3/3), 208 bytes | 0 bytes/s, done.

Total 3 (delta 0), reused 0 (delta 0)

To git@github.com:xxx/test1.git

  • [new branch] master -> master

    Branch master set up to track remote branch master from origin.

现在回过头来重新看一下创建本地仓库那几条命令。

git init 命令用于将当前目录变成git可管理的仓库。创建成功后,当前目录下会多出一个目录.git,

这个目录是Git来跟踪管理版本库的,所以千万不能删除;

git add 命令是将文件 添加 到仓库;

git commit 命令是将文件 提交 到仓库,参数-m 指示本次提交说明。

为什么git add 之后又要 git commit? 它们有什么区别?

这里需要说明下git的结构:

执行git init 命令的那个目录,也就是.git 所在的目录,通常称为工作区

而目录.git不算工作区,而是Git的版本库。

版本库中有很多东西,其中有个区叫暂存区(index),git add把文件添加进去,实际上就是把文件修改添加到暂存区。

git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。至于什么是分支,后面会讲到。

可以验证下刚刚说的,方法是通过git status命令。

修改一个文件文件之后,运行git add, 然后执行git status

git status 会告诉你目前你修改了那些文件,它是与版本库中当前分支比较的结果,例如

$ git status
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage) modified: README.md

再次运行git commit之后,git status 告诉你没有修改,这说明git commit将你的修改实实在在提交到版本库了。

$ git status
On branch dev
nothing to commit, working directory clean

不过,修改并没有推送到远程仓库,如果要同步远程仓库,还需要执行git push命令。

git remote add origin git@github.com:xxx/test1.git 命令是将本地库与远程库进行关联,远程库默认名称为origin

git push -u origin master命令是第一次推送master分支的所有内容,以后推送就无需添加参数 -u 了。

如何拷贝远程仓库内容到本地呢?

上面讲到从零开始创建本地仓库再与远程库关联,如果远程库已经有内容了,如何将其内容拷贝到本地呢?

即拷贝一个仓库,通常一条命令就可以搞定。

git clone git@github.com:xxx/test1.git

git分支管理

到目前为止,我们还没有创建任何分支, 当然master分支是创建仓库是默认自动创建的。

master分支是一个稳定的分支,一般只有经过测试的稳定版或者里程碑版本才被允许合并到master分支。

先来看看如何创建新的分支;

git checkout -b dev

或者

git branch dev

第一个命令的意思是创建一个新分支dev,并且* 切换 *到该分支下。

第二个命令只创建了新分支,但并没有切换分支。那么何为切换呢?

因为git需要知道你要操作的分支,那么多分支,它通过什么判别你要操作的分支呢?

git有一个HEAD指针,用它来指向当前待操作的分支。

要了解当前操作的分支,直接运行git branch即可:

$ git branch
* dev
master
test

分支前带星号的就是当前分支,也就是HEAD所指向的分支。

切换分支:

git checkout branch_name

合并分支:

比如要将dev 分支合并到master 分支:

git checkout master #切换到master分支首先
git merge --no-off -m "balbal" dev

参数--no-off表示禁用fast-forword。为什么要禁止?因为这种模式下,删除分支后,会丢掉分支信息。

git在团队协作中怎样运用?

一般的,项目有一个稳定的分支master以及开发分支dev;

master分支用来保存比较稳定的版本,比如里程碑版本,dev是一个比较活跃的分支,所有开发者的提交都首先merge到dev分支。

团队中每个人有一个分支,比如张三一个分支,李四一个分支,所有开发者的分支都和dev分支建立链接关系

git branch --set-upstream-to=origin/dev zhangsan

上述命令的意思是将本地分支zhangsan与远程分支dev进行关联,这样做的好处是,每次用户修改之前,可以先运行

git pull命令将dev上的最新修改拉取到本地分支,这样可以有效减少冲突。

如果你有多个分支,在一个分支上开发到一半(并没有提交),这时候有转向另一个分支,

会提示如下信息:

$ git checkout test
error: Your local changes to the following files would be overwritten by checkout:
README.md
Please, commit your changes or stash them before you can switch branches.
Aborting

没关系,如果你不想提交修改,没关系,运行git stash,该命令的意思是先把当前工作现场隐藏起来,等以后恢复现场后继续工作。

$ git stash
Saved working directory and index state WIP on dev: 3b86461 add a new line
HEAD is now at 3b86461 add a new line $ git stash list
stash@{0}: WIP on dev: 3b86461 add a new line

那怎么恢复呢?通过命令git stash pop,

$ git stash pop
On branch dev
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (ca81919d1e48fb73c1cca80f52e3408ca61ae70d)

通过git status验证:

$ git status
On branch dev
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a")

冲突了怎么办?

有时候害怕什么来什么,merge的时候提示冲突了怎么办?比如下面, 分支test 和 分支dev修改了同一行。

$ git merge test
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

首先可以通过git status 查看产生冲突的文件。

$ git status
On branch dev
You have unmerged paths.
(fix conflicts and run "git commit") Unmerged paths:
(use "git add <file>..." to mark resolution) both modified: README.md no changes added to commit (use "git add" and/or "git commit -a")

打开冲突文件,可以看到一些花花绿绿的特殊的符合,比如:

hi
world
yes, you are right
<<<<<<< HEAD
add by dev
=======
add by test branch
>>>>>>> test

git 用 <<<<<<<, =======, >>>>>>>来区分不同分支的修改。删除这些,保存你想要的,就可以了,例如:

hi
world
yes, you are right
add by dev and test branch

再次提交就可以了。

参考

廖雪峰GIT学习

git summary的更多相关文章

  1. Mac下JDK、Maven、Tomcat、Git开发安装及环境变量配置

    本文主要内容: - 1.Mac OS 10.11.6 [OS X EL Captain] - 2.Mac OS 安装Java 设置环境变量 - 3.Mac OS 安装Maven设置环境变量 - 4.M ...

  2. git 使用和安装

    http://www.git-scm.com/download/ http://www.git-scm.com/download/win http://www.git-scm.com/download ...

  3. Git - Mac 电脑使用 brew 更新 Git

    安装 Homebrew Homebrew 是一个软件包管理器.它的作用就是将软件包安装到自己的目录中,然后将其文件符号链接到 /usr/local.更多信息,请自行进入官网查看 https://bre ...

  4. csharp: Download SVN source

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. GitHub Toturial

    GitHub Toturial Git Summary 1. 设置姓名和email git config --global user.name "YuboFeng" git con ...

  6. Mac os安装golang开发环境

    为了能够愉快地进行golang编程,我们需要安装以下几样东西: 包管理Homebrew 语言环境golang 版本管理git 虚拟器docker 编译器Goland 我将按照这个顺序叙述整个安装过程 ...

  7. Asp.net core静态文件目录访问

    Asp.net core静态文件目录访问 如果使用Asp.net core来实现一个能够访问其它电脑上的资源 新建工程 选择项目框架 如何将静态文件注入到项目中 在startup.cs文件的Confi ...

  8. (六十五)c#Winform自定义控件-图标字体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  9. 2019-8-4-自动更新所有-Git-仓库

    title author date CreateTime categories 自动更新所有 Git 仓库 lindexi 2019-08-04 14:44:59 +0800 2019-08-01 2 ...

随机推荐

  1. Graph And Its Complement CodeForces - 990D(思维构造)

    题意: 图中有n个点,开始有a个连通块,然后连着的边断开,不连的边连上,变为b个连通块,输出原图的邻接矩阵. 解析: 原图中连通块大于1的图,经过上述操作后,一定变成只有1个连通块的图. 若n != ...

  2. C++运算符重载形式——成员函数or友元函数

    运算符重载是C++多态的重要实现手段之一.通过运算符重载对运算符功能进行特殊定制,使其支持特定类型对象的运算,执行特定的功能,增强C++的扩展功能. 运算符重载的我们需要坚持四项基本原则: (1)不可 ...

  3. java多线程 -- 创建线程的第三者方式 实现Callable接口

    Java 5.0 在 java.util.concurrent 提供了一个新的创建执行线程的方式:Callable 接口Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个 ...

  4. 【数学】【P5150】 生日礼物

    Description 给定 \(n\),求 \[\sum_{i}~\sum_j~[lcm(i,j)~=~n]\] input 一行一个整数代表 \(n\) Output 一行一个整数代表答案 Hin ...

  5. C++ public private protect 继承关系(链接)

    基础链接 总结:  public继承基类成员访问权限没有变化; protected继承基类public和protected权限变为protected,基类private不变. private继承基类p ...

  6. (转)Python中的generator详解

    本文转自:http://www.cnblogs.com/xybaby/p/6322376.html 作者:xybaby 注:本文在原文基础上做了一点点修改,仅仅作为个人理解与记忆,建议直接查看原文. ...

  7. GO_02:GO语言开篇

    Go的发展史 Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后 ...

  8. P1392 取数

    P1392 取数 题目描述 在一个n行m列的数阵中,你须在每一行取一个数(共n个数),并将它们相加得到一个和.对于给定的数阵,请你输出和前k小的取数方法. 说明 对于20%的数据,n≤8 对于100% ...

  9. 跟上Java8 - 日期和时间实用技巧

    原文出处:王爵nice 当你开始使用Java操作日期和时间的时候,会有一些棘手.你也许会通过System.currentTimeMillis() 来返回1970年1月1日到今天的毫秒数.或者使用Dat ...

  10. java的灵魂——反射

    前言:当我们在类加载的时候,除了把.class文件加载到内存,会把各个类存到各个类模板(class类型)对象上,相同的类只有一个类模板对象.连接:把类的二进制数据合并到JRE中 反射运行时探究和使用编 ...