zoukankan      html  css  js  c++  java
  • git

    Git基础
    一 简介
    1.什么是git,git有什么作用
    Git是用C语言开发的分布版本控制系统。版本控制系统可以保留一个文件集合的历史记录,并能回滚文件集合到另一个状态(历史记录状态)。另一个状态可以是不同的文件,也可以是不同的文件内容。举个例子,你可以将文件集合转换到两天之前的状态,或者你可以在生产代码和实验性质的代码之间进行切换。文件集合往往被称作是“源代码”。在一个分布版本控制系统中,每个人都有一份完整的源代码(包括源代码所有的历史记录信息),而且可以对这个本地的数据进行操作。分布版本控制系统不需要一个集中式的代码仓库。
     
    当你对本地的源代码进行了修改,你可以标注他们跟下一个版本相关(将他们加到index中),然后提交到仓库中来(commit)。Git保存了所有的版本信息,所以你可以转换你的源代码到任何的历史版本。你可以对本地的仓库进行代码的提交,然后与其他的仓库进行同步。你可以使用Git来进行仓库的克隆(clone)操作,完整的复制一个已有的仓库。仓库的所有者可以通过push操作(推送变更到别处的仓库)或者Pull操作(从别处的仓库拉取变更)来同步变更。
     
    Git支持分支功能(branch)。如果你想开发一个新的产品功能,你可以建立一个分支,对这个分支的进行修改,而不至于会影响到主支上的代码。
     
    2.一些重要的概念
    仓库(Repository):一个仓库包括了所有的版本信息、所有的分支和标记信息。在Git中仓库的每份拷贝都是完整的。仓库让你可以从中取得你的工作副本。
     
    分支(Branches):一个分支意味着一个独立的、拥有自己历史信息的代码线(code line)。你可以从已有的代码中生成一个新的分支,这个分支与剩余的分支完全独立。默认的分支往往是叫master。用户可以选择一个分支,选择一个分支叫做checkout。
     
    标记(Tags):一个标记指的是某个分支某个特定时间点的状态。通过标记,可以很方便的切换到标记时的状态。
     
    提交(Commit):提交代码后,仓库会创建一个新的版本。这个版本可以在后续被重新获得。每次提交都包括作者和提交者,作者和提交者可以是不同的人。
     
    URL:URl用来标识一个仓库的位置。
     
    修订(Revision):用来表示代码的一个版本状态。Git通过用SHA1 hash算法表示的id来标识不同的版本。每一个 SHA1 id都是160位长,16进制标识的字符串.。最新的版本可以通过HEAD来获取。之前的版本可以通过"HEAD~1"来获取,以此类推。
     
    索引(index):Git 需要将代码的变化显示的与下一次提交进行关联。举个例子,如果你对一个文件继续了修改,然后想将这些修改提交到下一次提交中,你必须将这个文件提交到索引中,通过git add file命令。这样索引可以保存所有变化的快照。
     
    3.在windows平台上安装git
    下载地址:https://git-scm.com/,下载windows版本
    在“Configuring the line ending conversions”选项中,选择第一个,表示是在windows系统安装,第二个表示是在Unix系统安装
    在桌面右击,则会出现Git Gui和Git Bash,说明git安装成功,选择Git Bash,则可以里面进行相关操作,也可以直接点击桌面上的Git Bash按钮
     
    4.git查看
    右击进入Git Bash,或者直接点击Git Bash桌面图标,进入git命令行窗口。
    输入git --version  查看git版本号
    输入git conf,双击tab键,自动补全git config
    如果输入git config --,会出现config后面可以加的其他一些可能的参数
     
    4.git基本操作
    (1)可以通过“git config”命令来配置Git,这个命令有3个选项:--system, --global,--local,分别对应Git上3级配置文件。
    第一个是/etc/gitconfig文件,和--system对应,这是全局配置文件,修改这个文件,将会影响系统上所有的用户,所有的仓库。
    第二个是你家目录下的/.gitconfig文件,与--global对应,修改它会对你当前用户的所有仓库产生影响。
    第三个是你仓库中的.git/.gitconfig文件,这是“git config”默认修改的配置文件,它只会对你当前仓库产生影响。
    它们的优先级的关系是:--system<--global<--local
    (2)在第一次使用Git时,你需要告诉你的协同开发者,你是谁以及你的邮箱,在你提交的时候,Git需要这两个信息。具体通过以下命令设置:
    git config --global user.name “Test OSS”
    git config --global user.email oss.lzu.edu.cn@gmail.com
    当然你也可以不用--global选项,但这意味这你在每一个仓库中都要这样设置。
    (3)查看git config的相关配置
    git config user.name
    git config --list
    git config --list --global
    (4)查看git文档
    方法:输入git config --help
    或输入git help config
    或者输入man git-config
     
    二 git本地仓库
    1.git仓库的基本知识
    获取git仓库有两种方法:git init和git clone。 Git做为一个资源管理和跟踪系统,如果想要把自己的文件托管在Git上,那么首先你得让Git知道你需要管理的文件在哪。比如说现在我有一个项目,它在test文件夹里,我想让Git管理这个项目,这个时候你需进入到这个目录,然后运行“git init”命令。这个时候Git就会在该目录下生成一个.git的隐藏目录,Git用来进行版本控制和内容跟踪的所有文件都在该文件夹下。

    处于git跟踪下的文件只具有三种状态:

    • Modified(working directory):被修改过的文件
    • Staged(staging area):通过git add添加到暂存区域的文件
    • Committed(git directory):通过git commit提交到仓库的文件

    所以,一般的git工作流程可能是这样:修改过某些文件,然后把这些文件添加都暂缓区,再提交到仓库中形成一个版本或快照,最后提交到git服务器上。而在中间,可能伴随着分支管理,分支切换,撤消与合并。

    可能有些人会觉得很奇怪,为什么git会有暂存区域这个概念,直接提交到仓库中不就ok了。其实这是git为了做版本控制用的,试想如果没有暂存区域,每修改一个文件,就会形成一个版本,太过频繁,不易于管理。暂存区域其实就是下一个版本的文件清单,你可以自由控制该往仓库中提交什么文件,这也可以避免在一个版本中包含一些中间文件,比如编译后的文件。
    整个git仓库的指令大体如下:
    git本地仓库的指令:
    git仓库有三个区域,git的工作主要是围绕这三个区域进行的
    working directory:工作区,也就是我们日常写代码的地方,维护着一个树形结构
    history repository:历史仓库,是commit指向的一个树形结构
    staging area: 暂存区,相当于是工作区与历史仓库中间的一个缓存,它代表的是我们工作时需要提交的一个状态,维护的是一个虚拟的结构
    添加文件到暂存区,然后会把暂存区整体的状态commit到历史仓库,还可以从历史仓库里检测到文件到暂存区
    所对应的具体操作如下:
    git add:添加文件到暂存区
    git commit:将暂存区整体状态提交到历史仓库
    git status:查看工作区和暂存区的区别,确保提交的是我们所需要的
    git rm:从暂存区里删掉不需要的东西
    git mv:从工作区中移动或者重命名文件,再把它们添加到暂存区里面去
    git ignore:确保工作区里面一些不希望被添加到暂存区和历史仓库中的文件不被添加进去
    3.git基本流程
    (1)初始化仓库
    初始化仓库有两种情况,一种是直接在一个空目录里建立一个项目,这时候你可以这样干:git init

    另一种是从其他机器复制一个仓库,比如这样:

    git clone git://git2.kernel.org/pub/scm/git/git.git (远程仓库)

    git clone https://github.com/jquery/jquery.git (远程仓库)

    git clone git@github.com:wengpingbo/MicroBlog.git (远程仓库)

    git clone /home/oss/test.git (本地仓库)
    复制完后,就会在当前目录下生成一个工作目录,名字以仓库名字命名。如果你不想指定目录,那就在上面的命令后加一个目录就ok了。比如我想把test仓库放到oss仓库中:git clone /home/oss/test.git oss。
    以git init为例,具体建立一个git本地仓库:
    第一步:在d盘下建立名为get_repository的文件夹->输入/d 回车后输入mkdir get_repository再回车
    第二步:初始化get_repository仓库->输入git init get_repository->结果:Initialized empty Git repository in D:/get_repository/.git/,说明仓库建立成功
    第三步:进入该文件夹下的.git文件夹,输入cd get_repository/.git/->结果:/d/get_repository/.git/(GIT_DIR!),说明这是一个git工作区间
    第四步:查看该文件夹,输入ls->结果:config description HEAD hooks/ info/ objects/ refs/
    整个过程如图:
    对应到d盘中查看,发现get_repository文件夹下的.git文件夹里的内容即为上面的结果
    (2)创建文件和添加文件
    创建文件a:touch a       添加a文件到暂存区a:git add a      添加所有文件:git add .    查看当前状态:git status
    具体操作过程:
    进入到d:get_repository文件夹对应的工作区下,输入touch a enter,touch b enter,创建a,b两个文件,再输入git add a b enter,将a,b两个文件添加到暂存区里,使用git status查看,发现新增了两个文件a和b,并提示有两个新的文件将要被提交,该提交为初次提交,具体过程如图:
    提交这两个文件,输入git commit -m "Initial commit",其中Initial commit为提交的信息,这样就可以将这两个文件提交到历史仓库中了 。注意,如果只输入git commit,并不会按你想象的那样跳出一个提交成功的提示,而是直接跑到了你在配置中指定的编辑器中了。仔细看一下,原来是让你给这个版本做一些备注,随便写点什么,然后保存退出就ok了。具体见图:
     
    (3)删除操作
    删除a(从工作区和暂存区删除):git rm a     查看已经被提交的文件:git ls      移除文件a(只从暂存区中删除) :git rm --cached a       重置改变游标指向:git reset
    输入git rm a删除a文件,输入ls查看文件,显示只有b,输入git status,显示a被删除的信息,输入git reset HEAD a将其还原,如图(部分操作有误,将get_repository改为myRepository)
    输入ls进行查看,此时还是只有b文件,输入git checkout a,将a拷下来,再次输入ls,查看,此时有a和b,如图:
    如果删除a文件使用的是git rm --cached a,通过git status查看会告诉我们有一个还没有被跟踪的文件,可以使用git add a将a文件重新添加到暂存区。
    (4)移动文件操作
    有时文件需要移动一下路径或重命名,可以使用git mv来实现
    将a文件重命名为c,输入git mv a c,输入git status查看,此时会提示我们有一个rename的操作
    修改回去,在自己的工作目录下将a修改为c,用git status查看一下
    提示我们a被删除了还没被暂存,新的文件c还没有被跟踪
    输入git add a c,再输入git status查看
    提示我们a被rename成c
    其实git mv做了以下几件事:在工作区中将所需要的文件重命名或移动,而且在暂存区中把原有的文件名删除,再把新的文件添加进暂存区
    (5)ignore操作
    使用git ignore避免把一些不需要的文件添加进历史仓库里。
    假设在get_repository中有一些不需要的文件,输入vim .gitignore,在vim窗口下输入*.xml表示忽略所有以xml类型的文件,返回后输入git status查看,如图:
    注意:vim窗口的使用规则是:进入到vim窗口之后是普通模式,按i键进入insert模式,这样就可以输入message了。输入完成后,按ESC键进入命令模式,输入冒号(在窗口下面),再输入x,回车即可。
    红字显示的是只剩下这三个文件
    4.本地分支与合并
    (1)分支
    建立一个仓库,在仓库中添加两次记录并提交,具体过程如下:
    第一步:首先创建一个仓库,输入git init git_checkout_merge
    第二步:进入到git_checkout_merge中添加一些记录,输入vim master.txt,做一个初始的提交。这两步过程如图:
    vim窗口输入的内容如下:
    第三步:输入git add .再输入git commit -m "Initial commit on master",结果如图:
    第四步:增加第二个历史提交,步骤同上,如图

    第五步:创建一个新的分支test,输入git branch test,但是此时我们仍在master分支上,如何切换到test分支呢,输入git checkout test即可,如图:
    第六步:在test分支中做一些修改,输入vim master.txt,vim窗口如下:
    第七步:再创建text.txt文件,将这些修改commit到test的历史记录里,整个过程如图:
    分支每提交一次,就指向最新一次的提交
    (2)分支合并
    某个时间点需要将多个分支合并到一个分支上去
    第一步:先切换到master分支,然后再用master指向的那个commit创建分支my_merge,并且切换到这个分支上去,输入vim master.txt,通过vim窗口修改master的内容
    vim窗口修改如下:
    第二步:将修改添加到历史记录里
    第三步:查看其目录结构,输入git lol
    第四步:转到master分支,将test_merge分支合并到master中,输入git merge my_merge,如图:
    这样的一个merge,并不需要产生新的提交,只需要把工作区和暂存区恢复到my_merge上面的一个状态,然后把master指向my_merge指向的那个commit即可。显示merge之后的图
    若想放弃这次合并,输入git merge --abort
    若要继续合并,则需要处理冲突的文件,输入vim master.txt,进入vim窗口,里面的内容如下
    对其进行修改,只保留master上面的内容:
    将master.txt添加进暂存区,git commit即可
    此时会提示这是一个merge的commit,如果不修改merge的内容,可以直接退出,这就形成了一个commit
    (3)查看与对比历史记录
    先用git log --oneline --decorate --graph --all查看各个分支,再输入git show 4ecba9b或者git show master,或者git show HEAD
    输入git show master^2,指向master的第二个副提交,这些信息包括了提交者,提交信息,提交与副提交的差异
     
    使用git show --oneline master^2来输出一个简短的信息
    使用git show --stat master^2来显示提交所作出的一些改变的统计信息
    使用git log查看完整的历史信息,如果篇幅较长,可以使用空格向下翻页,点击b向上翻页
    (4)使用git diff输出工作区与暂存区的差异
    由于本次还没有差异,因此不会输出,通过vim窗口修改master.txt,再git diff

    此时的结果如上图所示,此时将master.txt保存到暂存区,使两个之间一致,再次输出,结果如图:
    使用git diff --cached显示暂存区与历史提交之间的差异:
    指定当前工作区与历史提交之间的差异,还可以指定当中某一个特定文件的差异,使用git diff HEAD~2 -- master.txt,如图:
    比较当前历史和前两个历史版本,输入git diff HEAD HEAD~2即可查看
    可以使用git diff --color-words用颜色标注不同的地方
    (5)撤销修改
    git checkout:用于切换和创建分支,还可以用来还原工作区
    git reset:还原暂存区
    git clean:清除还没有添加进暂存区的文件,也就是git还没有跟踪的文件
    git revert:产生一个新的提交来覆盖之前的提交所产生的修改
    通过vim master.txt修改vim窗口里的内容,输入git diff
    输入git status
    输入git checkout -- master.txt,该操作实际上是用暂存区的内容覆盖掉操作区的内容,再通过vim来查看master文件,发现之前的修改已经被恢复了。在vim窗口中继续随意修改,通过git status查看,发现文件已修改,过程如图:
    输入git reset master.txt,在输入git diff --cached,发现两者之间已经没有差异了
     
    三 git 远程仓库
    1.查看当前的远程库git remote -v
    在你commit完之后,你可能想把自己的代码提交到github或者其他git服务器上,与他人交流共享,这时候就需要和远程服务器打交道了。
    如果你是在本地建立起的仓库,默认情况下是没有任何服务器地址的,如果你是从其他服务器复制过来的仓库,这个服务器地址会自动添加到你的仓库中,你可以这样查看:git remote -v
    2.添加一个远程库git remote add [shortname] [url]
    一个仓库可以有多个服务器地址,这就意味着,你可以从不同的人手中复制同一个仓库,但这并不会打乱你自己的分支,哪怕双方的分支名字都一样。假如你现在在和另外两个人做同一个项目中的同一个分支,你发现A的一个模块正是你想要的,你想把他的代码合并到你现在的版本中,这时候你可以这样做:

    git remote add code_a git://url/test.git  //添加对方的地址,code_a是别名

    git fetch code_a  //复制对方的仓库到本地,但不合并,git pull会自动合并

    git merge code_a/master //把对方master分支合并到自己当前版本下
    注意:git fetch是抓取code_a仓库有的,但是本地仓库没有的信息, fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。
    3.推送数据到远程仓库git push [remote-name] [branch-name]
    合并完之后,你可能想提交你的代码到其他的服务器上,这时候你可以先把要提交的服务器地址添加进来,然后这样做:git push origin master
    上面的命令就是把自己master的分支提交到名字为origin的服务器上
    4.git pull
    如果设置了某个分支用于跟踪某个远端仓库的分支,可以使用 git pull 命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。在日常工作中我们经常这么用,既快且好。实际上,默认情况下 git clone 命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支)。所以一般我们运行 git pull,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工作目录中当前分支。
    5.查看远程仓库信息
    以通过命令 git remote show [remote-name] 查看某个远程仓库的详细信息
     
    四 补充
    1.撤消改动
    当你执行某个命令之后,突然发现,自己写错了,或者漏了一个文件,这时候怎么办?
    如果你提交得太早,忘了添加某些文件,你可以这样做:
    git commit -m ‘add something ’
    git add file1
    git commit --amend

    2.如果你添加了不该添加的文件,你可以这样挽回:

    git add . //把所有的文件都添加进去

    git reset HEAD readme  //把readme文件从暂存区域去除

    3.如果你发现你编辑错了一个文件,你想把它恢复到上一个版本的状态,这时候你可以这样:

    git checkout -- filename1 //只撤消这一个文件

    4.如果你觉得这个版本糟糕透了,想完全回滚到上一个版本,你可以干如下事情:

    git reset --hard HEAD^
     
     
     
     
     
     
  • 相关阅读:
    K3Wise K3List.OCX引入dotnet问题处理方法
    k3wise dotnet开发老单据时序簿工具条添加按钮
    c#调用dotnet写的com组件碰到注册失败的错误的补救方法
    bat注册dotnet com
    dotnet动态加载以及卸载dll的代码
    c#获取com对象的progid
    jpg和png的区别
    Fragment的FragmentTransaction 的commit()和commitAllowingStateLoss()以及commitNow()和commitNowAllowingStateLoss()
    Java泛型类型擦除与运行时类型获取
    rxjava介绍
  • 原文地址:https://www.cnblogs.com/lyy-2016/p/5638993.html
Copyright © 2011-2022 走看看