Git 使用小结

GIT

原文连接

1. 仓库

你可以把一个仓库想象成一个数据库,在那里你的版本控制系统存储了项目积攒的所有版本和元数据(metadata)。在Git中,仓库只是一个在你项目的根目录下名为.git的隐藏文件夹。你只要知道有这个文件夹存在就足够了。你没有必要也不需要去接触或是搞明白这个文件夹。

1.1. 创建本地仓库

有两种方法可以来获取一个本地仓库到你的计算机上:

  • 如果在本地计算机中已经存在了一个项目,但是尚未纳入版本控制系统中,你可以为这个项目初始化一个新的仓库。
    在项目的根目录下执行git init命令即可,就会在项目的根目录下创建.git的隐藏目录。
  • 如果你需要得到一个已经纳入版本控制系统中的项目,而且它已经存放在一个远程服务器中。你只需要知道这个仓库的URL地址,然后克隆(clone)到你的本地计算机中就可以了。
    在项目的跟目录下执行git clone url,然后Git将会完整地克隆这个仓库到你的本地计算机上。

2. 暂存区

在git中文件有两种状态:

  • 未被追踪的文件(untracked):表示版本控制系统不能监视或者追踪它的改动。一般情况下未被追踪的文件会是那些新建的文件,或者是那些没有被纳入版本控制系统中的忽略文件
  • 已追踪的文件(tracked):Git会监视它的任何改动,并且你可以提交或放弃对它修改。

当想要提交已追踪的文件上的改动时,黄金法则是“一次提交只对应一个相关的改动”,但是在实际的开发情况中不可能保证一次改动只对应一个目的,这就须要引入一个新的概念暂存区(Staging Area)。它可以让你来确定哪些修改将被打包在下次提交中。因为在Git中并不是简单的把每一个改动后的文件都自动打包起来的。相反,每一次提交打包都要 “手动完成”,哪些改动需要被打包在下次提交中都需要你自己决定,是否需要 “添加到暂存区域” 或者简单的说 “被暂存”。

2.1. 得到上一次commit后的所有改动详情

使用git status命令,如果没有改动则显示“nothing to commit, working tree clean”信息,否则显示如下信息。

  • Changes not staged for commit 改动的文件,但没有打包在下次提交中。
  • Changes to be committed 改动的文件,并且已打包在下次提交中。
  • Untracked files 未被追踪的文件。

2.2. 提交修改

git bash工具中,提交修改的步骤为:

  1. 使用git add命令将改动添加到暂存区,提交到暂存区后,如果想要取消使用git rm命令
  2. 使用git commit -m命令提交修改

命令示例:

git add file1 [file2 ...]
git commit -m "注释"

在idea中可以认为了弱化了add命令,直接选择commit选项后,会出现文件选择列表,手动选择文件后直接执行commit。

2.2.1. 增强

情况一:当我们在commit后如果想要修改上一次 commit 内容。可以通过 git commit --amend -m '注释' 命令修改最后一次commit信息。

Note:

  • --amend只会修改最后一次的commit内容,结果为使用新的commit id节点替换最后一次commit id节点,并没有增加新的commit节点。
  • --amend只修改本地分支的最后一次commit信息,如果最后一次的commit已经push到远程分支,则远程分支的commit不会被修改。

详情参见维持整洁的 Git 提交记录的【善用 git commit --amend】章节。
如果想要修改倒数第二个commit,参见Git进阶–你可能不知道的很好用Git功能的【一、刚提交的代码,发现需要微调一下】章节。

情况二:如果我们在commit之后发现,漏掉了部分需要commit的文件或者想要commit新的内容确不想增加新的commit节点。可以通过 git commit --amend --no-edit 命令将此次commit合并到上一次的commit中。

git add .
git commit --amend --no-edit

这样并不会生成新的commit节点,而是在上一次的commit中的进行了补充。

通过情况一和情况二,即可保证每次commit都是有效信息。

2.3. 查看commit历史记录

显示在项目中所有的提交历史记录可以使用 git log [-p] 命令,通过-p选项显示commit中的diffs信息。

所有在这个项目中的commit将按时间顺序显示出来,最新的提交会出现在最上面。如果说所有的提交历史记录不能完全显示在一个屏幕中,在命名行界面的最下方会显示一个冒号“:”。这时你可以使用空格键来跳转到下一页,或是使用 “q” 键退出这个界面。

每个提交记录都包括(除其他事项外)如下的元数据(metadata):

  • Commit Hash
  • Author Name & Email (提交人的姓名和电子邮箱)
  • Date (日期)
  • Commit Message (提交注释)

3. 关于远程仓库

在版本控制系统上,大约90%的操作都是在本地仓库(local repository)中进行的:暂存,提交,查看状态或者历史记录等等。除此之外,如果仅仅只有你一个人在这个项目里工作,你永远没有机会需要设置一个远程仓库(remote repository)。

只有当你需要和你的开发团队共享数据时,设置一个远程仓库才有意义。你可以把它想象成一个 “文件管理服务器”,利用这个服务器可以与开发团队的其他成员进行数据交换。

3.1. 位置

本地仓库位于每一个团队成员的本地计算机上。相反,远程仓库则被设置在一个能被所有团队成员访问到的远程服务器上,基本上都是在互联网上或者是本地局域网中。

3.2. 创建远程仓库

  • 方法一,假如已经存在了一个本地仓库,并且你想以这个本地仓库作为远程仓库的基准,你使用--bare参数来可以克隆这个本地仓库。
  • 方法二,假如你想要新建一个空的远程仓库,你可以使用git init命令,并且同时也要加上--bare参数。

3.3. origin

当克隆一个远程仓库的同时,Git 会自动为你的记录下远程仓库的链接地址。默认使用 origin 这个名字当做连接名来标识你所克隆的原始仓库
ps:origin这个名字是默认的,用于当做远程仓库连接(url)的名称。

通过git remote -v命令可以看到本地仓库已经连接的远程仓库,如果是通过克隆远程仓库的方式创建的本地仓库,则默认只有名称为origin的fetchpush两个不同的urls,默认情况下两个urls是相同的。

3.4. 连接一个远程仓库

如果是直接在本地计算机上创建了一个本地仓库,执行git remote -v命令会发现没有任何结果,这表示没有任何一个本地仓库到远程的连接。这种情况下,当尝试做任何远程操作之前必须先把本地方库先连接到一个远程仓库上去:

通过以下命令将本地仓库连接到远程仓库

git remote add 自定义的连接名称 远程仓库URL地址

注意:可以对一个本地仓库设置很多个远程链接,这是没有数量限制的。

执行命令首次创建连接后,仅可以通过git remote -v命令看到建立的远程仓库连接,本地目录并无任何变化。

通过git remote add命令,我们仅仅建立了一种本地仓库和远程仓库的关系,并不会进行任何数据交换。

概念
远程数据是一个快照(Snapshot)
Git 会在你的本地仓库中保存远程数据的信息(例如分支,提交等等)。但是它并不是实时地连接到你的远程仓库上的。例如,其他团队成员在这个远程仓库中所提交的新改动或是发布的分支,是不能自动地与你分享的,因为你必须明确地告诉 Git 去升级你的本地仓库!
关于远程的分支,远程的提交等等信息Git 不会在后台自动更新这些信息。

要获取或更新远程仓库的内容,你必须明确地请求这个数据。在这里可以使用最为常用的抓取(Fetch)操作来完成:

git fetch [连接名称] [from fetch的URL]

执行完命令后,本地仓库目录中依旧没有变化,fetch操作不会改动你任何的本地分支或是在你工作副本中的文件。这个操作仅仅为你从一个特定远程仓库下载你所需要的数据,并设置为可见。你可以在之后决定是否需要整合这些新的改动本地项目中来。
通过git branch -va命令可以列出远程跟踪分支和本地分支信息。

$ git branch -va
其中
-a 列出远程跟踪分支和本地分支。
-v 在列表模式下,显示每个头的 sha1 值和 commit subject信息,以及与远程分支的关系(如果有)。
-vv 在-v的基础上显示远程分支的名称
一般直接使用 git branch -vva 即可

想要真正的在远程仓库的某个分支上工作,并且切换当前工作副本的内容,需要创建一个基于远程分支的本地分支,通过执行git checkout --track 连接名称/远程分支名命令。

git checkout --track 连接名称/远程分支名

git checkout --track命令完成了如下工作:

  1. 它创建了一个同名的本地分支。
  2. 它检出(checkout)了这个新建的的分支,把它设置成当前的本地 HEAD (使用git branch -vva查看时分支名称前带有星标的即为head分支),然后更新了你的工作副本,并且关联到分支文件的最新版本上去。
  3. 由于我们使用了--track参数,它会在新的本地分支和它所位于的远程分支之间创建一个跟踪联系(tracking relationship)有个这个跟踪联系后,后续我们在本地操作该分支时,命令中就不需要再使用连接名

在执行git clone命令时,其实就相当于执行了git remote addgit fetchgit checkout --trach命令。

概念:
跟踪分支
一般来说,分支之间并无任何关系。然而我们可以定义一个本地分支去 “跟踪(track)” 一个远程分支。这样 Git 就会通知你,如果那个被跟踪的远程分支发生了一些新的提交,而它们并不存在于这个关联的本地分支中时:

  • 如果在你的本地分支上提交了一些改动,而且你也并没有提交和推送它到远程仓库中。相对于这些提交来说你的本地分支就 “领先(ahead)” 于那些它所对应的远程分支。
  • 如果团队的其他开发人员提交并且发布了一些改动到远程仓库中,这时远程仓库就拥有了那些你还没有下载到本地仓库的提交。你的本地仓库就 “落后(behind)” 于它所关联的远程仓库。

如果分支之间存在跟踪联系,当你使用 git status 命令时,Git 显示出所有关联分支上的差异。

当在本地分支的工作副本中完成一些新的修改后,通过git push命令将修改推送到远程分支。git push命令将会把当前 HEAD 分支上所有新的提交上传到它所关联的远程分支上去。

概念
回顾跟踪联系
git push命令默认地要求我们为它提供两个信息:

  • 你想要推送到哪一个远程仓库上去?
  • 你想要推送到哪个远程仓库上的哪一个分支上去?

完整命令为:
git push 连接名称 远程分支名称
我们已经通过git checkout --track设置了跟踪联系,也就是说我们已经为那个本地分支定义了一个 “ 远程对应的(remote counterpart)” 分支。在我们使用 git push and git pull 命令时,我们不需要特别地给出那些参数, Git 会自动地使用这些已经定义好的 “跟踪” 信息。

3.5. 将本地分支推送到远程仓库(push)

在你明确地决定将一个本地分支发布到远程仓库之前,这些在你本地计算机上创建的分支是不能被其他的团队成员看到的,它只是你的私有分支。这就意味着,你可以保留某些改动仅仅在你私有的本地分支上,而与其他团队成员分享一些其它分支上的改动。

通过git push命令将本地分支推送到远程仓库中,具体命令如下:

git push [-u] [连接名称] [分支名称]

这个命令会告诉 Git 来发布你当前本地的 HEAD 分支到连接名称指定的远程仓库上,并命名为“分支名称”(在本地和其对应的远程分支保持相同的分支名是非常有必要的)。
-u选项会自动地在你本地的同名分支和新建的远程分支之间创建一个跟踪链接。执行git branch -vva命令来显示分支信息,并且在方括号中就会显示出这个建立的跟踪联系。如果已经和远程分支建立跟踪联系,则不需要使用-u选项。

3.6. 整合远程分支中的内容到本地分支(pull)

当团队其他成员在远程仓库中提交到了新的改动时,可以通过如下命令检查新的改动:

git fetch [连接名]
git log [连接名称/远程分支名]

通过git pull命令将远程仓库中的改动整合到本地副本中,该命令将会从远程分支下载所有的新的提交到你的本地副本中来。它实际上就是一个 抓取(fetch) 命令(下载数据)和一个 合并(merge) 命令(整合那些下载的数据到你的本地副本)的组合。

git pull [连接名称] [远程分支名称]

git push 命令一样,如果你本地的 HEAD 分支还没有创建任何一个与远程分支的跟踪联系,你就必须告诉 Git,要从哪一个远程仓库上的哪一分支中抓取数据(例如 git pull origin master)。如果已经存在了一个跟踪链接,只需要简单键入 git pull 就足够了。

整合的目标并不基于存在什么样的跟踪链接,它总是会被整合到你的本地 HEAD 分支中,也就是你的工作副本。

在idea中使用git工具update project时,会有如下两种选项,两种选项的差别参见维持整洁的 Git 提交记录的【善用 git rebase -i】章节,以及Rebase 代替合并

  • merge incoming changes into the current branch
  • rebase the current branch on top of incoming changes

4. GIT分支

在 Git 上的分支功能并不是可选的,你永远会工作在一个分支中的(当前的 “active”,或者 “checked out”,或者 “HEAD”分支)。
那么 Git 是如何知道你当前在哪个分支上工作的呢? git status 命令输出的第一行会向我们显示出当前在哪个分支上。

master分支是 Git 在建立项目的同时自动建立的。尽管可以删除或者是为它重命名,但是你很少能看到一个没有master分支的项目,因为基本上大家都会保留它。
master其实就是一个和别的分支一样普通的分支而已!

4.1. 本地创建新分支

通过git branch 分支名命令创建一个新分支。

注意:git branch 分支名命令仅仅创建了一个新的分支,但不会自动切换到这个分支上去。

使用git branch -v命令来显示出所有在项目中已经存在的分支,-v选项可以 显示出更多的信息。

4.2. 暂时保存更改

一个被提交了的改动会被永久地保存在仓库(repository)中。然而,在你日常工作中你经常需要“暂时地”保存一下你的一些本地改动。例如,如果你正在开发一个新的功能,但是与此同时又得到了一个错误报告,并且需要马上修复它,而你现在的本地改动又和这个错误毫无关系,因此你必须暂时地停止新功能的开发,来开始着手修复这个错误。并且你还想要保存那些已完成的开发工作,以便之后能继续来完成它。

像这样的情况会随时发生,比如你必须要开始一个新的工作,而在你的当前工作版本中还有一些并不想立即提交的本地改动。在处理好这些本地改动的同时,我们还需要把当前的工作副本(working copy)清理出来,Git 提供的储藏(Stash) 功能可以非常好地解决这个问题。

概念:
储藏(Stash)
可以把储藏想象成一种剪贴板,它会获取你工作副本(working copy)中的所有改动,并且保存到一个新的剪贴板上。然后你就会得到一个不存在任何改动的工作副本。
之后你随时都可以重新调回那些保存在剪贴板中的改动到你的工作副本中来,从而继续你之前没有完成的工作。
你可以建立多个储藏单元,不仅仅局限于存储一组变化。同样,储藏也会不绑定在你所处的当前分支或是任何其它分支上,如果你想要调回任意一个储藏单元,它的改动将会被应用在你当前的 HEAD 分支上。

执行git stash命令,当前工作副本中的全部改动已经被安全地保存在一个剪贴板上了。当我们希望继续对它们进行工作时,我们都可以随时轻松地调回它。

通过git stash list命令,获取已经保存的全部stash列表。
最新建立的储藏单元会被显示在列表的最上面,被命名为stash@{0} ,最新的那个储藏单元名称永远是stash@{0}。早前建立的储藏单元会拥有一个更高的数字。
当你想要调回一个之前建立的储藏单元,有两种方法:

  • 使用 git stash pop 命令,它将调回最新的一个储藏单元,并且把它从剪贴板中删除掉。
  • 使用 git stash apply <stashname> 命令,它将调回那个你所给出的储藏单元,而这个储藏单元还会保留在剪贴板中。你可以随时使用 git stash drop <stashname> 命令能够来删除指定名称的stash。

4.3. checkout到指定分支

通过git checkout 分支名命令可以checkout到指定分支上去。

git checkout 分支名这个命令会为我们完成两件事:

  • 它会让 HEAD 指针指向这个"分支名"分支。
  • 它会替换你工作目录(working directory)中的所有文件,并且完全匹配它们的版本到"分支名"分支。

4.4. 分支的模式

git-flow 模式会预设两个主分支在仓库中:

  • master 只能用来包括产品代码。你不能直接工作在这个master分支上,而是在其他指定的,独立的特性分支中工作。不直接提交改动到master分支上也是很多工作流程的一个共同的规则。
  • develop 是你进行任何新的开发的基础分支。当你开始一个新的功能分支时,它将是_开发_的基础。另外,该分支也汇集所有已经完成的功能,并等待被整合到master分支中。

这两个分支被称作为长期分支。它们会存活在项目的整个生命周期中。

4.4.1. release分支

当你认为现在在develop分支的代码已经是一个成熟的release版本时,这意味着:第一,它包括所有新的功能和必要的修复;第二,它已经被彻底的测试过了。如果上述两点都满足,那就是时候开始生成一个新的release了

4.4.2. hotfix分支

很多时候,仅仅在几个小时或几天之后,当对release版本作做全面测试时,可能就会发现一些小错误。
在这种情况下,git-flow提供一个特定的hotfix作流程(因为在这里不管使用feature分支流程,还是release分支流程都是不恰当的)。

5. 名词解释

5.1. fork

参见 fork解释

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值