Git快速入门

Posted lovelylazycat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Git快速入门相关的知识,希望对你有一定的参考价值。

版本控制工具 - Git   快速入门

注意: 本教程只适合快速入门和日常操作,Git的精髓远远没这么少.

版本控制

  团队开发犹如多线程处理数据,并发访问数据永远带来线程安全问题,稍有不甚就会带来"脏读"现象,从而导致整个业务逻辑或数据被破坏.

  开发团队多个人访问一份源代码,极有可能出现多个人同时修改源代码的情况;或一个人在访问源代码时并不是最新的.这意味你可能在使用别人改过的接口,或者使用着已经过时的调用.这对整个项目来说是灾难性的打击.

  对项目进行版本控制是极其有必要的.不管是开源还是闭源软件,每一次对源代码的修改都应该进行说明并公示给大家看.这样我们能清晰地看到各个版本的改动,从而减少冲突的可能.

  一个好的版本控制工具应该能记录源代码的每一次修改.包括具体修改的内容,时间,修改者等信息.并且提供一个服务器,让团队能上传源代码.在项目出现BUG的时候,能够紧急回溯(退回之前的稳定版本).或者是,更高级的,让项目有不同的分支,每个分支都能独立地开发,最后提供整合功能...

  版本控制工具有千千万万(团队开发离不开版本控制),有收费的和免费的.早先比较有名的有SVN, CVS.这是两个基于CS架构的工具,提供版本管理的功能.

  后来,Linus Torvalds(著名操作系统Linux之父)开发了一款全新的版本工具: Git.
  Git是一款开放源代码的、分布式的、拥有强大分支管理的(按照元数据管理分支)、使用SHA-1 hash算法的强大版本控制工具.其仅仅是一款软件,而不再是CS架构.取代S的是远程仓库(著名的GitHub).它提供的强大版本控制、分析工具,让世界所有程序员震撼.

  目前,世界上几乎95%的团队在使用Git.数不胜数的明星级开源项目使用Git管理(例如: nodeJs, jQuery, tomcat, redis, hadoop, maven, cocos2d, ......)

  即使是个人使用,也可以用Git控制自己编写的小项目,可以把自己造的轮子上传到GitHub供全世界分享.或者是获取开源项目的源代码供学习使用...

Git安装

  Git开源免费,可以在官方网站获取Git.其支持目前的主流操作系统(Windows, Linux, Mac OS).

  需要注意,Git最早是运行在Linux下的,命令行管理才是它的强项.虽然它提供图形界面程序,但是不建议过分依赖.在安装后,使用

git --version

可以查看Git的版本号.

  如果你使用的是Windows操作系统,不建议使用自带的控制台(cmd)来使用git.

  Git for Windows自带了一个bash,在安装的时候注意勾选这个.这样,在安装完成之后,在任意目录下右键,你会发现一个叫做"Git Bash Here"的选项.
  选这个,便会弹出一个bash终端,在这里面输入命令即可.

  再次提醒,Git for Windows会自带一个图形界面工具,但是不要过多使用它.

  另外,一些开发工具会自动集成一些git操作.例如,Intellij IDEA.一些文本编辑器可以安装git插件,VSCode和SublimeText甚至是vim都有强大的git插件.当然,使用这些的前提是你的电脑里头必须有Git.

配置Git

  在安装Git后,需要向git提供你的用户名和邮箱.

  有两种方法配置,如果你用的是类UNIX系统(Linux/Mac OS),修改以下配置文件:

/etc/gitconfig

  Windows一般在你C盘家目录(C:\\Users\\xxx)下的.gitconfig文件.

  

  如果你不喜欢修改配置文件,可以简单地调用下面两个命令:

git config --global user.name "your username."
git config --global user.email [email protected]

  

  这两个命令会去直接修改之前的git配置文件.如果是类UNIX用户记得使用root权限.

  没有root权限可以去掉global,这样在家目录修改,仅影响当前用户.

  想查看你的配置,使用:

git config --list

Git原理

  

  因为本教程注重实践而不是理论,下面仅对git原理做个简单的描述.

工作区:

  git基本概念,所有的git操作均在工作区下进行.
  它是你电脑中的一个目录.这个目录必定包含一个叫做.git的隐藏目录.
  其基本作用就是,存放源代码.你的所有开发均在此处进行.

暂存区:

  位于.git/index,存放暂时提交的修改.
  例如你改动了某个源代码,你需要把这改动提交到暂存区.

版本库: 
  存放项目版本,也就是提交的源代码.
  可以把位于暂存区的改动提交到版本库,这就是真正地提交了代码.
  特别的是版本库有多个分支,每个分支可以存放不同的源代码.
  有一个HEAD指针指向了当前使用的分支.

  简单说,整个git管理可以分为以下几步:

初始化git工作区 -> 编写源代码 -> 把修改提交到暂存区 -> 把暂存区的修改提交到版本库

  初始化只需要进行一次,每次对工作区的修改(包括增加文件、修改文件、删除文件、增加目录、删除目录)都会被git记录下来.你可以把改动提交到暂存区,再把暂存区的改动提交到版本库.最后一步是真正的提交它会在版本中记录下你这次提交的内容、时间、提交者(还记得你之前设置的用户名和邮箱么?).

  git一个重要的概念是,分支.每个项目可以有多个分支,分支可以存放不同的代码.每个分支有自己的名字、标识符等信息.每个工作区都有一个当前分支的概念,这是HEAD指针指向的分支.你的每次提交默认都是把修改提交到当前分支上.你可以随意地创建分支、切换分支、合并分支等.这些操作在后面介绍.

 创建本地工作区

使用git就必须有工作区.要创建工作区,很简单,下面几步可以完成:

  1. 创建一个空的目录,或者进入一个已经存放一些源代码的目录(注意,这个目录原来不能是git工作区,或者被其他版本工具管理.)
  2.  进入目录,使用命令:

git init

这会在当前目录创建.git目录.  

  这样,这个目录就变成了git工作目录.
  一个简单的栗子:

$ cd ~
$ mkdir gitTest
$ cd gitTest
$ git init

  注意,千万不要修改.git目录下的东西,不然会破坏整个git的结构.

基本操作 

  在你编写完代码之后,使用以下的命令可以查看当前工作区的状态:

git status

显示出来你对工作区做了哪些修改.
  显示的修改有两部分,一部分是红色的;一部分是绿色的(如果你在tty下或者Windows自带的cmd下,可能区分不出颜色.)

    红色的是没有提交到暂存区的修改.
    绿色的是已经提交到暂存区的修改.

  以下的命令可以把修改提交到暂存区:

git add [<file1>][,<file2>][,<file3>]...

FILE表示你修改的文件.

  栗子: 把修改后的a.txt文件和b.cpp文件提交到暂存区

$ git status
未暂存的更改:
  a.txt
  b.cpp
$ git add a.txt b.cpp
$ git status
 已暂存的更改:
  a.txt
  b.cpp

  注意,暂存只是临时缓存.这些修改不会真正地提交到项目版本库中.

  如果你修改了大量文件,一个一个写很麻烦,使用以下命令可以直接把工作区的所有更改提交到暂存区:

git add .

  当然,你可以把暂存区的修改撤回.使用如下命令可以把暂存的更改移出暂存区:

git reset HEAD [-- <file>]

加-- FILE,表示把单一文件移出暂存区,否则是把整个暂存区清空.

  你也可以把暂存区的修改提交到版本库,注意,以下的操作只会提交暂存区的修改,未暂存的修改不会提交:

git commit -m "在这里编写注释"

-m后面是本次提交的注释,这个是必要的,一般建议用英文书写.
commit和add不同.commit会把修改正式提交,这是很难撤回的.而add只是暂存,可以随时撤回

  在commit之后,你再git status一下,会发现所有绿色的更改已经消失了.因为git把它们提交了,不再会把它们当作更改了.

  那么,以下是提交git常用的命令:

$ git status            # 先查看一下工作区的状态,在操作前最好都输入一遍,这是一个好的习惯
$ git add .             # 把所有更改提交到暂存区
$ git commit -m "xxx"   # 把更改提交到版本库

  大多数情况下,你都可以使用这三个命令把你修改的代码提交了.

  git add .和git commit可以合并:

git commit -a

  如果你不想每次都输入一下git add . 那么可以使用-a参数,这会直接把修改提交到暂存区,然后把暂存区的内容提交到版本库.但是,这个操作仅仅适用于修改操作,不适用于新建、删除操作.

  那么,上面的命令也可以这么写:

$ git status
$ git commit -am "xxx"        # 省去git add .

  如果我们想查看一个项目的提交历史,可以使用:

git log [--oneline]

加上oneline,表示显示简洁版本(每个提交占据一行)

分支

  分支是版本控制的重要概念,它可以让我们从当前主分支分开来,单独开发.

  也就是说,分支的产生离不开另外一个分支.有点类似OOP中的继承概念,或UNIX编程的fork()系统调用.子分支刚开始和父分支是一样的,但是随后对子分支的修改不会影响父分支,二者是相互独立的.

  Git的分支模型有很大的亮点,这也是它的主要卖点(观察它的logo,不就是分支嘛...)
  Git的分支很特别,一般人实现分支可能是建立不同的文件夹.但是Git的工作区只有一个,所有的分支会共享这个目录.Git有一个元数据,记录了各个分支的状态,在你切换分支的时候,Git会自动把你的工作区更换为新分支的样子(不是新分支的文件删除,创建新分支的文件).

  这一切都是透明的.你只要知道怎么切换分支以及你当前工作区是哪个分支就行了.

  创建一个新的分支:

git branch BRANCH_NAME

BRANCH_NAME表示这个分支的名字.这会在当前工作区的基础上创建一个分支.
但是使用这个命令不会切换到这个新的分支上去.(还是在原有分支)

  注意,如果你的工作区一次commit都没有进行过,那么无法创建任何分支.
  如果你至少进行了一次commit,git会自动帮你建立一个叫做master的分支.
  所以以下的操作是错误的:

$ git init
$ git branch test    # 操作错误,因为这是一个新的工作区,没有任何commit,不能创建分支

  查看所有分支:

git branch

  这会列出所有已知分支,当前所处的分支前面会有一个"*"

  例如,创建一个test分支:

$ git branch           # 查看当前的分支
* master
$ git branch test      # 创建一个叫做test的分支
$ git branch           # 再次查看
* master
test

  这就创建了一个test分支.

  如果你想切换分支,使用:

git checkout BRANCH_NAME

这会切换到BRANCH_NAME这个分支上

  例如,切换到test分支上:

$ git branch           # 查看分支
* master
test 
$ git checkout test    # 切换到test分支
$ git branch           # 再次查看
master
* test

  前面说过,git会帮助我们保存分支的状态,下面给一个简单的栗子演示:

$ git branch                          # 看我现在在哪个分支
master
* test
$ touch a.txt                         # 这里创建一个a.txt文件
$ ls -a
.    ..    .git    a.txt
$ git add .
$ git commit -m "add file a.txt"      # 提交一下修改
$ git checkout master                 # 切换到master分支
$ ls -a                               # 查看目录,天呐!发现a.txt没了!
.    ..    .git 
$ git checkout test                   # 紧张的我赶紧切换回test分支看看
$ ls -a                               # 查看目录,发现a.txt又回来了!
.    ..    .git    a.txt

  注意,git记录的分支状态是提交的状态,而不是工作区或者暂存区的状态.

  也就是说,在切换分支的时候,暂存区和工作区的修改状态仍然会保留.
  观察以下操作:

$ git branch
* master
test
$ touch a.txt b.txt                      # 创建两个文件,但是不提交
$ ls -a
.    ..    .git    a.txt    b.txt
$ git checkout test
$ ls -a                                  # 切换到test,发现两个文件还是存在
.    ..    .git    a.txt    b.txt
$ git add .
$ git commit -m "add a.txt and b.txt"    # 把a.txt和b.txt提交到test分支
$ git checkout master                    # 回到master
$ ls -a                             # 发现a.txt和b.txt没了,因为它们被提交到test分支了
.    ..    .git

  理解了上面两个栗子,你可以知道:

  git保存的分支针对的提交的修改.对于未提交的(包括暂存区内的),git不会记录在分支中.这也就是为什么我在master分支建立的文件跑到test分支提交了,回到master分支发现它们不见了的原因.

  分支可以删除,使用:

git branch -d BRANCH_NAME

  删除分支会删除其所有提交,是一件很危险的事情.

  分支合并

    这是git最有趣的一个东西.
    所谓"万物归宗",子分支从父分支衍生出来,在之后的某一天可能会和父分支合并.

git merge BRANCH_NAME

这会把指定分支和当前分支合并.注意,当前分支是主动方,指定分支是被动方.

    分支合并还涉及到合并冲突,是一个话题.由于本教程是简单基础教材,所以这里不再陈述.
    读者可以自行查看git参考手册.
    如果你只是一个普通的程序员,一般不会面对分支合并.这一般是由项目管理者做的.

    你可使用:

git log --online --graph

查看整个项目的分支创建、合并路线,git会以拓扑图的形式显示,非常形象.

远程仓库


  git只是在本机操作的.如果要跟全世界人民或自己团队的小伙伴分享你的项目,可以使用一个"代码托管平台"的东西.

问: 虾米是代码托管平台?
答: 其实很好理解,就像托儿所一样,你可以把自己的小孩托管在那里.你可以随时把他接走,或者是,送过去.
     代码托管平台是你把自己的代码上传到别人的服务器,从而让别人查看、下载你的代码.
     当然,如果你觉得别人的服务器不安全,而你又恰好是一个土豪,你可以自己搭建一个Git服务器.

  目前的主流代码托管平台几乎都是基于git的.也就是说你可以直接通过git把你的代码推送到服务器上.

  比较有名的托管平台是GitHub,它非常好用,本身不仅仅可以存放代码,还集成了很多Git操作.也就是说,你可以把它看作一个大型的、远程的Git图形界面工具.

  可惜的是,GitHub是国外的网站,因为一些众所周知的原因,你访问这个网站会比较卡(你懂的...).
  所以我们可以选择一些国内的代码托管网站替换,主要好处是速度快,而且用起来和GitHUb差别不是特别大.
  比较好的是: 码云 和 Coding

  网站的用法在每个网站有详细的教程,这里不再废话.
  这里只介绍两个操作: 把代码上传到远程仓库、从远程仓库获取代码.

  每个项目都有一个唯一的url,这个在项目的主页可以获取.这个url一般是基于SSH或者HTTPS协议.
  使用命令:

git clone [-b branch] url [dir]

这可以把url的项目拷贝到本地.

-b参数指定把项目的哪个分支clone到本地,不加会clone所有分支,并且进入主分支(一般是master)
dir表示你把项目clone到本地的哪个位置,不指定会clone到当前目录下,目录名为项目名称.

  如果这个项目是私有项目,git会让你输入用户名和密码,不想每次都输入可以配置ssh密钥并把密钥保存到远程.

  具体操作可以百度,这里不再介绍了.

  如果要把本地的代码上传到服务器,需要了解git工作区的一个特殊属性: remote  这表示远程仓库的位置,每个git工作区可以保存多个remote属性.
  如果你是从远程仓库clone的代码,工作区会有一个默认remote,代表这个代码是从哪里来的.

  你可以使用以下命令查看remote:

git remote

  如果你不是clone的项目,而是在本机新建的,默认下remote是空的.也就是你此时不能把代码推送到远程仓库.
  要想推送,必须手动加上remote:

git remote add remote_name url

remote_name 表示这个remote的名称,可以自己指定,习惯设为origin
url 表示远程仓库的位置,你可以在你的代码托管平台获取(注意流程,先要在网站创建一个新的项目,再获取url)

  在添加好remote之后,可以使用下面的命令把本地代码提交到远程仓库:

git push remote_name [branch]

remote_name 表示要把代码提交到哪个仓库.
branch 是可选的,表示提交哪个分支,默认提交当前分支.

  一个简单的栗子: 把代码推送到远程仓库

$ git remote add origin https://xxx/xxx
$ git push origin dev                      # 注意推送的是dev分支

  试想一个场景: 你的团队的其它人修改了代码并上传到了远程仓库,那么你在开发前,最好先下载他修改的内容.

  这使用下面的操作:

git pull remote_name [branch]

注意它和clone的区别:

  • clone是把整个源代码下载下来,它可以在任意地方操作.
  • pull是把别人对源代码的修改与本地已经存在的源代码做一个"合并",其必须在本地工作区进行.注意这可能会产生冲突(例如:你们两个都对同一个文件进行了修改)在产生冲突的时候,git提供merge的功能,它可以自动处理一些简单的冲突.对于一些它处理不了的冲突,它会把冲突的内容在文件中罗列出来,让用户自己修改.这点在你使用git的过程中会慢慢有感触的.

另外,在pull之前,确保你的工作区是干净的.也就是说,先把所有未提交的修改处理了,否则git不会让你pull的.

强烈建议: 在多人开发的时候,每次写代码前都pull一下,确保你目前储存的是最新代码.

 

以上是关于Git快速入门的主要内容,如果未能解决你的问题,请参考以下文章

Python开发笔记:git&github 快速入门

git &github 快速入门

Git快速入门

git & github 快速入门

git &github 快速入门

git &github 快速入门