标签 Git 下的文章

如果您从未使用过 Git,甚至可能从未听说过它。莫慌张,只需要一步步地跟着这篇入门教程,很快您就会在 GitHub 上拥有一个全新的 Git 仓库。

在开始之前,让我们先理清一个常见的误解:Git 并不是 GitHub。Git 是一套版本控制系统(或者说是一款软件),能够协助您跟踪计算机程序和文件在任何时间的更改。它同样允许您在程序、代码和文件操作上与同事协作。GitHub 以及类似服务(包括 GitLab 和 BitBucket)都属于部署了 Git 程序的网站,能够托管您的代码。

步骤 1:申请一个 GitHub 账户

在 GitHub.com 网站上(免费)创建一个账户是最简单的方式。

选择一个用户名(比如说,octocat123),输入您的邮箱地址和密码,然后点击 Sign up for GitHub。进入之后,您将看到下方插图的界面:

步骤 2:创建一个新的仓库

一个仓库( repository),类似于能储存物品的场所或是容器;在这里,我们创建仓库存储代码。在 + 符号(在插图的右上角,我已经选中它了) 的下拉菜单中选择 New Repository。

给您的仓库命名(比如说,Demo)然后点击 Create Repository。无需考虑本页面的其他选项。

恭喜!您已经在 GitHub.com 中建立了您的第一个仓库。

步骤 3: 创建文件

当仓库创建完毕后,界面将和下方一致:

不必惊慌,它比看上去简单。跟紧步骤。忽略其他内容,注意截图上的 “...or create a new repository on the command line,”。

在您的计算机中打开终端。

键入 git 然后回车。如果命令行显示 bash: git: command not found,在您的操作系统或发行版 安装 Git 命令。键入 git 并回车检查是否成功安装;如果安装成功,您将看见大量关于使用该命令的说明信息。

在终端内输入:

mkdir Demo

这个命令将会创建一个名为 Demo 的目录(文件夹)。

如下命令将会切换终端目录,跳转到 Demo 目录:

cd Demo

然后输入:

echo "#Demo" >> README.md

创建一个名为 README.md 的文件,并写入 #Demo。检查文件是否创建成功,请输入:

cat README.md

这将会为您显示 README.md 文件的内容,如果文件创建成功,您的终端会有如下显示:

使用 Git 程序告诉您的电脑,Demo 是一个被 Git 管理的目录,请输入:

git init

然后,告诉 Git 程序您关心的文件并且想在此刻起跟踪它的任何改变,请输入:

git add README.md

步骤 4:创建一次提交

目前为止,您已经创建了一个文件,并且已经通知了 Git,现在,是时候创建一次 提交 commit 了。提交可以看作是一个里程碑。每当完成一些工作之时,您都可以创建一次提交,保存文件当前版本,这样一来,您可以返回之前的版本,并且查看那时候的文件内容。无论何时您修改了文件,都可以对文件创建一个上一次的不一样的新版本。

创建一次提交,请输入:

git commit -m "first commit"

就是这样!刚才您创建了包含一条注释为 “first commit” 的 Git 提交。每次提交,您都必须编辑注释信息;它不仅能协助您识别提交,而且能让您理解此时您对文件做了什么修改。这样到了明天,如果您在文件中添加新的代码,您可以写一句提交信息:“添加了新的代码”,然后当您一个月后回来查看提交记录或者 Git 日志(即提交列表),您还能知道当时的您在文件夹里做了什么。

步骤 5: 将您的计算机与 GitHub 仓库相连接

现在,是时候用如下命令将您的计算机连接到 GitHub 仓库了:

git remote add origin https://github.com/<your_username>/Demo.git

让我们一步步的分析这行命令。我们通知 Git 去添加一个叫做 origin (起源)的,拥有地址为 https://github.com/<your_username>/Demo.git(它也是您的仓库的 GitHub 地址) 的 remote (远程仓库)。当您提交代码时,这允许您在 GitHub.com 和 Git 仓库交互时使用 origin 这个名称而不是完整的 Git 地址。为什么叫做 origin?当然,您可以叫点别的,只要您喜欢(惯例而已)。

现在,我们已经将本地 Demo 仓库副本连接到了其在 GitHub.com 远程副本上。您的终端看起来如下:

此刻我们已经连接到远程仓库,可以推送我们的代码 到 GitHub.com(例如上传 README.md 文件)。

执行完毕后,您的终端会显示如下信息:

然后,如果您访问 https://github.com/<your_username>/Demo,您会看到截图内显示的情况:

就是这么回事!您已经创建了您的第一个 GitHub 仓库,连接到了您的电脑,并且从你的计算机推送(或者称:上传)一个文件到 GitHub.com 名叫 Demo 的远程仓库上了。下一次,我将编写关于 Git 复制(从 GitHub 上下载文件到你的计算机上)、添加新文件、修改现存文件、推送(上传)文件到 GitHub。


via: https://opensource.com/article/18/1/step-step-guide-git

作者:Kedar Vijay Kulkarni 译者:CYLeft 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在之前的教程中,我们已经学习了在机器上安装 git。本教程,我们将讨论如何使用 git,比如与 git 一起使用的各种命令。所以我们开始吧。

设置用户信息

这应该是安装完 git 的第一步。我们将添加用户信息 (用户名和邮箱),所以当我们提交代码时,会产生带有用户信息的提交信息,这使得跟踪提交过程变得更容易。要添加用户信息,命令是 git config:

$ git config --global user.name "Daniel"
$ git config --global user.email "[email protected]"

添加完用户信息之后,通过运行下面命令,我们将检查这些信息是否成功更新。

$ git config --list

我们应该能够看到输出的用户信息。

GIT 命令

新建一个仓库

为了建立一个新仓库,运行如下命令:

$ git init

查找一个仓库

为了查找一个仓库,命令如下:

$ git grep "repository"

与远程仓库连接

为了与远程仓库连接,运行如下命令:

$ git remote add origin remote_server

然后检查所有配置的远程服务器,运行如下命令:

$ git remote -v

克隆一个仓库

为了从本地服务器克隆一个仓库,运行如下代码:

$ git clone repository_path

如果我们想克隆远程服务器上的一个仓库,那克隆这个仓库的命令是:

$ git clone repository_path

在仓库中列出分支

为了检查所有可用的和当前工作的分支列表,执行:

$ git branch

创建新分支

创建并使用一个新分支,命令是:

$ git checkout -b 'branchname'

删除一个分支

为了删除一个分支,执行:

$ git branch -d 'branchname'

为了删除远程仓库的一个分支,执行:

$ git push origin:'branchname'

切换到另一个分支

从当前分支切换到另一个分支,使用

$ git checkout 'branchname'

添加文件

添加文件到仓库,执行:

$ git add filename

文件状态

检查文件状态 (那些将要提交或者添加的文件),执行:

$ git status

提交变更

在我们添加一个文件或者对一个文件作出变更之后,我们通过运行下面命令来提交代码:

$ git commit -a

提交变更到 head 但不提交到远程仓库,命令是:

$ git commit -m "message"

推送变更

推送对该仓库 master 分支所做的变更,运行:

$ git push origin master

推送分支到仓库

推送对单一分支做出的变更到远程仓库,运行:

$ git push origin 'branchname'

推送所有分支到远程仓库,运行:

$ git push -all origin

合并两个分支

合并另一个分支到当前活动分支,使用命令:

$ git merge 'branchname'

从远端服务器合并到本地服务器

从远端服务器下载/拉取变更到到本地服务器的工作目录,运行:

$ git pull 

检查合并冲突

查看对库文件的合并冲突,运行:

$ git diff -base 'filename'

查看所有冲突,运行:

$ git diff

如果我们在合并之前想预览所有变更,运行:

$ git diff 'source-branch' 'target-branch' 

创建标记

创建标记来标志任一重要的变更,运行:

$ git tag 'tag number' 'commit id' 

通过运行以下命令,我们可以查找 commit id :

$ git log

推送标记

推送所有创建的标记到远端服务器,运行:

$ git push -tags origin

恢复做出的变更

如果我们想用 head 中最后一次变更来替换对当前工作树的变更,运行:

$ git checkout -'filename'

我们也可以从远端服务器获取最新的历史,并且将它指向本地仓库的 master 分支,而不是丢弃掉所有本地所做所有变更。为了这么做,运行:

$ git fetch origin
$ git reset -hard master

好了,伙计们。这些就是我们使用 git 服务器的命令。我们将会很快为大家带来更有趣的教程。如果你希望我们对某个特定话题写一个教程,请通过下面的评论箱告诉我们。像往常一样, 欢迎您的各种意见和建议。


via: http://linuxtechlab.com/beginners-to-pro-guide-for-git-commands/

作者:Shusain 译者:liuxinyu123 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

像大多数新手一样,我一开始是在 StackOverflow 上搜索 Git 命令,然后把答案复制粘贴,并没有真正理解它们究竟做了什么。

Image credit: XKCD

我曾经想过:“如果有一个最常见的 Git 命令的列表,以及它们的功能是什么,这不是极好的吗?”

多年之后,我编制了这样一个列表,并且给出了一些最佳实践,让新手们甚至中高级开发人员都能从中发现有用的东西。

为了保持实用性,我将这个列表与我过去一周实际使用的 Git 命令进行了比较。

几乎每个开发人员都在使用 Git,当然很可能是 GitHub。但大多数开发者大概有 99% 的时间只是使用这三个命令:

git add --all
git commit -am "<message>"
git push origin master

如果你只是单枪匹马,或者参加一场黑客马拉松或开发一次性的应用时,它工作得很好,但是当稳定性和可维护性开始成为一个优先考虑的事情后,清理提交、坚持分支策略和提交信息的规范性就变得很重要。

我将从常用命令的列表开始,使新手更容易了解 Git 能做什么,然后进入更高级的功能和最佳实践。

经常使用的命令

要想在 仓库 ( repo ) 中初始化 Git,你只需输入以下命令即可。如果你没有初始化 Git,则不能在该仓库内运行任何其他的 Git 命令。

git init

如果你在使用 GitHub,而且正在将代码推送到在线存储的 GitHub 仓库中,那么你正在使用的就是 远程 ( remote ) 仓库。该远程仓库的默认名称(也称为别名)为 origin。如果你已经从 Github 复制了一个项目,它就有了一个 origin。你可以使用命令 git remote -v 查看该 origin,该命令将列出远程仓库的 URL。

如果你初始化了自己的 Git 仓库,并希望将其与 GitHub 仓库相关联,则必须在 GitHub 上创建一个,复制新仓库提供的 URL,并使用 git remote add origin <URL> 命令,这里使用 GitHub 提供的 URL 替换 <URL>。这样,你就可以添加、提交和推送更改到你的远程仓库了。

最后一条命令用在当你需要更改远程仓库时。如果你从其他人那里复制了一个仓库,并希望将远程仓库从原始所有者更改为你自己的 GitHub 帐户。除了改用 set-url 来更改远程仓库外,流程与 git remote add origin 相同。

git remote -v
git remote add origin <url>
git remote set-url origin <url>

复制仓库最常见的方式是使用 git clone,后跟仓库的 URL。

请记住,远程仓库将连接到克隆仓库原属于的帐户。所以,如果你克隆了一个属于别人的仓库,你将无法推送到 GitHub,除非你使用上面的命令改变了 origin。

git clone <url>

你很快就会发现自己正在使用分支。如果你还不理解什么是分支,有许多其他更深入的教程,你应该先阅读它们,再继续下面的操作。(这里是一个教程)

命令 git branch 列出了本地机器上的所有分支。如果要创建一个新的分支,可以使用命令 git branch <name>,其中 <name> 表示分支的名字,比如说 master。

git checkout <name> 命令可以切换到现有的分支。你也可以使用 git checkout -b 命令创建一个新的分支并立即切换到它。大多数人都使用此命令而不是单独的 branch 和 checkout 命令。

git branch
git branch <name>
git checkout <name>
git checkout -b <name>

如果你对一个分支进行了一系列的更改,假如说此分支名为 develop,如果想要将该分支合并回主分支(master)上,则使用 git merge <branch> 命令。你需要先检出(checkout)主分支,然后运行 git merge develop 将 develop 合并到主分支中。

git merge <branch>

如果你正在与多个人进行协作,你会发现有时 GitHub 的仓库上已经更新了,但你的本地却没有做相应的更改。如果是这样,你可以使用 git pull origin <branch> 命令从远程分支中拉取最新的更改。

git pull origin <branch>

如果您好奇地想看到哪些文件已被更改以及哪些内存正在被跟踪,可以使用 git status 命令。如果要查看每个文件的更改,可以使用 git diff 来查看每个文件中更改的行。

git status
git diff --stat

高级命令和最佳实践

很快你会到达一个阶段,这时你希望你的提交看起来整洁一致。你可能还需要调整你的提交记录,使得提交更容易理解或者能还原一个意外的有破坏性的更改。

git log 命令可以输出提交的历史记录。你将使用它来查看提交的历史记录。

你的提交会附带消息和一个哈希值,哈希值是一串包含数字和字母的随机序列。一个哈希值示例如下:c3d882aa1aa4e3d5f18b3890132670fbeac912f7。

git log

假设你推送了一些可能破坏了你应用程序的东西。你最好回退一个提交然后再提交一次正确的,而不是修复它和推送新的东西。

如果你希望及时回退并从之前的提交中检出(checkout)你的应用程序,则可以使用该哈希作为分支名直接执行此操作。这将使你的应用程序与当前版本分离(因为你正在编辑历史记录的版本,而不是当前版本)。

git checkout c3d88eaa1aa4e4d5f

然后,如果你在那个历史分支中做了更改,并且想要再次推送,你必须使用强制推送。

注意:强制推送是危险的,只有在绝对必要的时候才能执行它。它将覆盖你的应用程序的历史记录,你将失去之后版本的任何信息。

git push -f origin master

在其他时候,将所有内容保留在一个提交中是不现实的。也行你想在尝试有潜在风险的操作之前保存当前进度,或者也许你犯了一个错误,但希望在你的版本历史中避免尴尬地留着这个错误。对此,我们有 git rebase。

假设你在本地历史记录上有 4 个提交(没有推送到 GitHub),你要回退这是个提交。你的提交记录看起来很乱很拖拉。这时你可以使用 rebase 将所有这些提交合并到一个简单的提交中。

git rebase -i HEAD~4

上面的命令会打开你计算机的默认编辑器(默认为 Vim,除非你将默认修改为其他的),提供了几个你准备如何修改你的提交的选项。它看起来就像下面的代码:

pick 130deo9 oldest commit message
pick 4209fei second oldest commit message
pick 4390gne third oldest commit message
pick bmo0dne newest commit message

为了合并这些提交,我们需要将 pick 选项修改为 fixup(如代码下面的文档所示),以将该提交合并并丢弃该提交消息。请注意,在 Vim 中,你需要按下 a 或 i 才能编辑文本,要保存退出,你需要按下 Esc 键,然后按 shift + z + z。不要问我为什么,它就是这样。

pick 130deo9 oldest commit message
fixup 4209fei second oldest commit message
fixup 4390gne third oldest commit message
fixup bmo0dne newest commit message

这将把你的所有提交合并到一个提交中,提交消息为 oldest commit message。

下一步是重命名你的提交消息。这完全是一个建议的操作,但只要你一直遵循一致的模式,都可以做得很好。这里我建议使用 Google 为 Angular.js 提供的提交指南。

为了更改提交消息,请使用 amend 标志。

git commit --amend

这也会打开 Vim,文本编辑和保存规则如上所示。为了给出一个良好的提交消息的例子,下面是遵循该指南中规则的提交消息:

feat: add stripe checkout button to payments page

- add stripe checkout button
- write tests for checkout

保持指南中列出的 类型 ( type ) 的一个优点是它使编写更改日志更加容易。你还可以在 页脚 ( footer ) (再次,在指南中规定的)中包含信息来引用 问题 ( issue ) 。

注意:如果你正在协作一个项目,并将代码推送到了 GitHub,你应该避免重新引用(rebase)并压缩(squash)你的提交。如果你开始在人们的眼皮子底下更改版本历史,那么你可能会遇到难以追踪的错误,从而给每个人都带来麻烦。

Git 有无数的命令,但这里介绍的命令可能是您最初几年编程所需要知道的所有。


Sam Corcos 是 Sightline Maps 的首席开发工程师和联合创始人,Sightline Maps 是最直观的 3D 打印地形图的平台,以及用于构建 Phoenix 和 React 的可扩展生产应用程序的中级高级教程网站 LearnPhoenix.io。使用优惠码:freecodecamp 取得 LearnPhoenix 的20美元。

(题图:GitHub Octodex)


via: https://medium.freecodecamp.org/git-cheat-sheet-and-best-practices-c6ce5321f52

作者:Sam Corcos 译者:firmianay 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

不要让 git 命令中的错误抹去你数天的工作

 title=

今天我的同事几乎失去了他在四天工作中所做的一切。由于不正确的 git 命令,他把保存在 stash 中的更改删除了。在这悲伤的情节之后,我们试图寻找一种恢复他所做工作的方法,而且我们做到了!

首先警告一下:当你在实现一个大功能时,请将它分成小块并定期提交。长时间工作而不做提交并不是一个好主意。

现在我们已经搞定了那个错误,下面就演示一下怎样从 stash 中恢复误删的更改。

我用作示例的仓库中,只有一个源文件 “main.c”,如下所示:

 title=

它只有一次提交,即 “Initial commit”:

 title=

该文件的第一个版本是:

 title=

我将在文件中写一些代码。对于这个例子,我并不需要做什么大的改动,只需要有什么东西放进 stash 中即可,所以我们仅仅增加一行。“git diff” 的输出如下:

 title=

现在,假设我想从远程仓库中拉取一些新的更改,当时还不打算提交我自己的更改。于是,我决定先 stash 它,等拉取远程仓库中的更改后,再把我的更改恢复应用到主分支上。我执行下面的命令将我的更改移动到 stash 中:

git stash

使用命令 git stash list 查看 stash,在这里能看到我的更改:

 title=

我的代码已经在一个安全的地方,而且主分支目前是干净的(使用命令 git status 检查)。现在我只需要拉取远程仓库的更改,然后把我的更改恢复应用到主分支上,而且我也应该是这么做的。

但是我错误地执行了命令:

git stash drop

它删除了 stash,而不是执行了下面的命令:

git stash pop

这条命令会在从栈中删除 stash 之前应用它。如果我再次执行命令 git stash list,就能看到在没有从栈中将更改恢复到主分支的之前,我就删除了它。OMG!接下来怎么办?

好消息是:git 并没有删除包含了我的更改的对象,它只是移除了对它的引用。为了证明这一点,我使用命令 git fsck,它会验证数据库中对象的连接和有效性。这是我对该仓库执行了 git fsck 之后的输出:

 title=

由于使用了参数 --unreachable,我让 git-fsck 显示出所有不可访问的对象。正如你看到的,它显示并没有不可访问的对象。而当我从 stash 中删除了我的更改之后,再次执行相同的指令,得到了一个不一样的输出:

 title=

现在有三个不可访问对象。那么哪一个才是我的更改呢?实际上,我不知道。我需要通过执行命令 git show 来搜索每一个对象。

 title=

就是它!ID 号 95ccbd927ad4cd413ee2a28014c81454f4ede82c 对应了我的更改。现在我已经找到了丢失的更改,我可以恢复它。其中一种方法是将此 ID 取出来放进一个新的分支,或者直接提交它。如果你得到了你的更改对象的 ID 号,就可以决定以最好的方式,将更改再次恢复应用到主分支上。对于这个例子,我使用 git stash 将更改恢复到我的主分支上。

git stash apply 95ccbd927ad4cd413ee2a28014c81454f4ede82c

另外需要重点记住的是 git 会周期性地执行它的垃圾回收程序(gc),它执行之后,使用 git fsck 就不能再看到不可访问对象了。

本文最初发表于作者的博客,并得到了转载授权。

(题图:opensource.com,附图:José Guilherme Vanz, CC BY)


via: https://opensource.com/article/17/8/recover-dropped-data-stash

作者:Jose Guilherme Vanz 译者:firmianay 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

使用 7 条简单的 Git 命令开始你的软件开发之旅

你是否曾经想知道如何学好 Git?你长期以来都是跌跌撞撞地在使用 Git。最终,你总需要掌握它的窍门。这就是我写这篇文章的原因,我将带你去启蒙之旅。这儿是我关于如何加快 Git 学习过程的基本指南。我将介绍 Git 的实际情况以及我使用最多的 7 条 Git 命令。本文主要针对有兴趣的开发人员和大学新生,他们需要关于 Git 的介绍以及如何掌握基础知识。


你可以往前继续阅读整篇文章,或者只读 TLDR; 部分,尽管这将使我很受伤。

TLDR;

在学习 Git 的过程中,请养成下面这些步骤的习惯:

  1. 随时使用 git status!
  2. 只更改那些你真正想更改的文件。
  3. git add -A 会是你的朋友。
  4. 随时使用命令 git commit -m "meaningful messages"。
  5. 做任何推送(push)之前先使用命令 git pull,但是这需要在你提交过一些更改之后。
  6. 最后,git push推送提交的更改。

良宵莫辜负

对任何开发人员来说,通常第一步都是选择一个广泛使用的地方托管他或她的代码库。那就是,GitHub。它是一切有关代码的聚集地。要理解 GitHub 的概念,你先需要知道什么是 Git。

Git 是一款基于命令行的版本控制软件,在 Windows 和 Mac 系统上也有几款可用的桌面应用。 Git 由 Linux 之父 Linus Torvalds 开发,Linus Torvalds 还是是计算机科学中最有影响力的人物之一。因为这一优势,Git 已经成为绝大多数软件开发人员关于共享和维护代码的标准。这一大段话,让我们将其细细道来。正如它的名字所说,版本控制软件 Git 让你可以预览你写过的代码的所有版本。从字面上来说, 开发人员的每个代码库都将永远存储在其各自的仓库中,仓库可以叫做任何名字,从 pineapple 到 express 都行。在此仓库开发代码的过程中,你将进行出无数次的更改,直到第一次正式发布。这就是版本控制软件如此重要的核心原因所在。它让作为开发人员的你可以清楚地了解对代码库进行的所有更改、修订和改进。从另外一个方面说,它使协同合作更容易,下载代码进行编辑,然后将更改上传到仓库。然而,尽管有了这么多好处,然而还有一件事可以锦上添花。你可以下载并使用这些文件,即使你在整个开发过程中什么事也没有做。

让我们回到文章的 GitHub 部分。它只是所有仓库的枢纽(hub),这些仓库可以存储在其中并在线浏览。它是一个让有着共同兴趣的人相聚的地方。

千里之行始于足下

OK,记住,Git 是一款软件,像任何其他软件一样,你首先需要安装它:

Git - 安装 Git,如果你希望从源代码安装 Git,你需要安装这些 Git 的依赖库: autotools —— 来自 git-scm.com

Tips:请点击上面的链接,然后按照说明开始。

完成了安装过程,很好。现在你需要在你的浏览器地址栏输入 github.com 访问该网站。如果你还没有帐号的话需要新创建一个帐号,这就是你的起舞之处。登录并创建一个新仓库,命名为 Steve ,没有什么理由,只是想要一个名为史蒂夫的仓库好玩而已。选中 “Initialize this repository with a README” 复选框并点击创建按钮。现在你有了一个叫做 Steve 的仓库。我相信你会为你自己感到自豪。

现在开始在使用 Git

现在是比较有趣的部分。你将把 Steve 克隆到你本地的机器上。可以把这个过程看作从 Github 上复制仓库到你的电脑上。点击 “clone or download” 按钮,你将看到一个类似下面这样的 URL:

https://github.com/yourGithubAccountName/Steve.git

复制这个 URL 并打开命令提示符窗口。现在输入并运行条命令:

git clone https://github.com/yourGithubAccountName/Steve.git

Abrakadabra!Steve 仓库已经被自动克隆到了你的电脑上。查看你克隆这个仓库的目录,你会看到一个叫做 Steve 的文件夹。这个本地的文件夹现在已经链接到了它的 “origin” ,也就是 GitHub 上的远程仓库。

记住这个过程,在你的软件开发工程人员的职业生涯中你一定会重复这个过程很多次的。完成所有这些准备工作之后,你就可以开始使用最普通且常用的 Git 命令了。

你现在已经开始在真实场景使用 Git 了

找到 Steve 目录并在该目录中打开命令提示符窗口,运行下面的命令:

git status

这会输出你的工作目录的状态,让你知道所有你编辑过的文件。这意味着它显示了远程库中和本地工作目录中之间的文件差异。status 命令被用来作为 commit 的模版,我将在这篇教程后面进一步谈论 commit 。简单的说,[git status][1] 告诉你你编辑过哪些文件,以给你一个你想要上传到远程库的概述。

但是,在你做任何上传之前,你首先需要做的是选择你需要发送回远程库的文件。使用下面命令完成:

git add

接着在 Steve 目录新建一个文本文件,可以取一个好玩的名字 pineapple.txt。在这个文件里面随便写些你想写的内容,返回命令提示符,然后再次输入 git status。现在,你将看到这个文件以红色出现在标记 “untracked files” 下面。

On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add <file>..." to include in what will be commited)

pineapple.txt

下一步就是将它添加到暂存区(staging)。暂存区可以看作是这样的一个环境:你做过的所有更改在提交时都将捆绑为一个更改而被提交。现在,你可以将这个文件加入暂存区:

git add -A

-A 选项意味着所有你更改过的文件都会被加到暂存区等待提交。然而, git add 非常灵活,它也可以像这样一个文件一个文件的添加:

git add pineapple.txt

这种方法让你有能力选择你想要暂存的每一个文件,而不用担心加入那些你不想改变的东西。

再次运行 git status,你会看到如下输出:

On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

new file:   pineapple.txt

准备好提交更改了吗?开始吧。

git commit -m "Write your message here"

Git commit 命令会将存储在暂存区中的文件和来自用户的用于描述更改的日志信息一起存储在一个新的地方。-m选项加入了写在双引号内的信息。

再次检查状态,你会看到:

On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean

所有的更改现在都被加入到一次提交当中了,同时会有一条与你所做相关的信息。现在你可以用 git push 将这次提交推送到远程库 “origin”了。这条命令就像字面意义所说,它会把你提交的更改从本地机器上传到 GitHub 的远程仓库中。返回到命令提示符,然后运行:

git push

你会被要求输入你的 GitHub 帐号和密码,之后你会看到类似下面的这些内容:

Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 280 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/yourGithubUserName/Steve.git
   c77a97c..08bb95a  master -> master

就是这样。你已经成功上传了你本地的更改。看看你在 GitHub 上的仓库,你会看到它现在包含了一叫做 pineapple.txt 的文件。

如果你是一个开发小组的一员呢?如果他们都推送提交到 “origin”,将会发生什么?这就是 Git 真正开始发挥它的魔力的时候。你可以使用一条简单的命令轻松地将最新版本的代码库 pull 到你本地的机器上:

git pull

但是 Git 也有限制:你需要有相匹配的版本才能推送到 “origin”。这意味着你本地的版本需要和 origin 的版本大致一样。当你从 “origin” 拉取(pull)文件时,在你的工作目录中不能有文件,因为它们将会在这个过程中被覆盖。因此我给出了这条简单的建议。在学习 Git 的过程中,请养成下面这些步骤的习惯:

  1. 随时使用 git status!
  2. 只更改那些你真正想更改的文件。
  3. git add -A 会是你的朋友。
  4. 随时使用命令 git commit -m "meaningful messages"。
  5. 做任何推送(push)之前先使用命令 git pull,但是这需要在你提交过一些更改之后。
  6. 最后,git push推送提交的更改。

嘿!你还在看这篇文章吗?你已经看了很久了,休息一下吧!

休息好了吗?好的!让我们来处理一些错误。如果你不小心更改了一些你本不应该更改的文件后怎么办呢?不需要担心,只需要使用 git checkout。让我们在文件 pineapple.txt 里更改一些内容:在文件中加入一行,比方说,“Steve is mega-awesome!” 。然后保存更改并用 git status 检查一下:

On branch master
Your branch is up-to-date with 'origin/master'.
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:   pineapple.txt

no changes added to commit (use "git add" and/or "git commit -a")

正如预料的那样,它已经被记录为一次更改了。但是,假如 Steve 实际上并不是很优秀呢?假如 Steve 很差劲呢?不用担心!最简单的还原更改的方式是运行命令:

git checkout -- pineapple.txt

现在你会看到文件已经恢复到了先前的状态。

但是假如你玩砸了呢?我是说,事情已经变得混乱,并且需要把所有东西重置到与 “origin” 一样的状态。也不需要担心,在这种紧急情况下我们可以享受 Git 的美妙之处:

git reset --hard

git reset 命令和 --hard 选项一起可以抛弃自上次提交以来的所有更改,有些时候真的很好用。


最后,我想鼓励你尽可能多地使用 Git。这是能够熟练使用它的最好学习方式。除此之外,养成阅读 Git 文档的习惯。一开始可能会有些云里雾里,但是过段时间后你就会明白它的窍门了。

希望你们(小伙子和姑娘们)读这篇文章的时候会和我写它时一样的开心。如果你认为这篇文章对别人有用,你尽可以与别人分享它。或者,如果你喜欢这篇文章,你可以在下面点下赞以便让更多的人看到这篇文章。


via: https://hackernoon.com/how-to-master-the-art-of-git-68e1050f3147

作者:Adnan Rahić 译者:zhousiyu325 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

对 Git 仓库的维护通常是为了减少仓库的大小。如果你从另外一个版本控制系统导入了一个仓库,你可能需要在导入后清除掉不必要的文件。本文着重于从一个 Git 仓库中删除大文件,并且包含下列主题:

  • 理解从 Git 的历史记录中删除文件
  • 使用 BFG 重写历史记录
  • 可选,使用 git filter-branch 重写历史记录
  • 垃圾回收

请格外小心.....

本文中的步骤和工具使用的高级技术涉及破坏性操作。确保您在开始之前仔细读过并备份了你的仓库,创建一个备份最容易的方式是使用 --mirror 标志对你的仓库克隆,然后对整个克隆的文件进行打包压缩。有了这个备份,如果在维护期间意外损坏了您的仓库的关键元素,那么你可以通过备份的仓库来恢复。

请记住,仓库维护对仓库的用户可能会是毁灭性的。与你的团队或者仓库的关注者进行沟通会是一个不错的主意。确保每个人都已经检查了他们的代码,并且同意在仓库维护期间停止开发。

理解从 Git 的历史记录中删除文件

回想一下,克隆仓库会克隆整个历史记录——包括每个源代码文件的所有版本。如果一个用户提交了一个较大的文件,比如一个 JAR,则随后的每次克隆都会包含这个文件。即使用户最终在后面的某次提交中删除了这个文件,但是这个文件仍然存在于这个仓库的历史记录中。要想完全的从你的仓库中删除这个文件,你必须:

  • 从你的项目的当前的文件树中删除该文件;
  • 从仓库的历史记录中删除文件——重写 Git 历史记录,从包含该文件的所有的提交中删除这个文件;
  • 删除指向旧的提交历史记录的所有 reflog 历史记录;
  • 重新整理仓库,使用 git gc 对现在没有使用的数据进行垃圾回收。

Git 的 “gc”(垃圾回收)将通过你的任何一个分支或者标签来删除仓库中所有的实际没用的或者以某种方式引用的数据。为了使其发挥作用,我们需要重写包含不需要的文件的所有 Git 仓库历史记录,仓库将不再引用它—— git gc 将会丢弃所有没用的数据。

重写存储库历史是一个棘手的事情,因为每个提交都依赖它的父提交,所以任何一个很小的改变都会改变它的每一个随后的提交的提交 ID。有两个自动化的工具可以做到这:

  1. BFG Repo Cleaner 快速、简单且易于使用,需要 Java 6 或者更高版本的运行环境。
  2. git filter-branch 功能强大、配置麻烦,用于大于仓库时速度较慢,是核心 Git 套件的一部分。

切记,当你重写历史记录后,无论你是使用 BFG 还是使用 filter-branch,你都需要删除指向旧的历史记录的 reflog 条目,最后运行垃圾回收器来删除旧的数据。

使用 BFG 重写历史记录

BFG 是为将像大文件或者密码这些不想要的数据从 Git 仓库中删除而专门设计的,所以它有一一个简单的标志用来删除那些大的历史文件(不在当前的提交里面):--strip-blobs-bigger-than

$ java -jar bfg.jar --strip-blobs-than 100M

大小超过 100MB 的任何文件(不包含在你最近的提交中的文件——因为 BFG 默认会保护你的最新提交的内容)将会从你的 Git 仓库的历史记录中删除。如果你想用名字来指明具体的文件,你也可以这样做:

$ java -jar bfg.jar --delete-files *.mp4

BFG 的速度要比 git filter-branch 快 10-1000 倍,而且通常更容易使用——查看完整的使用说明和示例获取更多细节。

或者,使用 git filter-branch 来重写历史记录

filter-branch 命令可以对 Git 仓库的历史记录重写,就像 BFG 一样,但是过程更慢和更手动化。如果你不知道这些大文件在哪里,那么你第一步就需要找到它们:

手动查看你 Git 仓库中的大文件

Antony Stubbs 写了一个可以很好地完成这个功能的 BASH 脚本。该脚本可以检查你的包文件的内容并列出大文件。在你开始删除文件之前,请执行以下操作获取并安装此脚本:

1、 下载脚本到你的本地的系统。

2、 将它放在一个可以访问你的 Git 仓库的易于找到的位置。

3、 让脚本成为可执行文件:

$ chmod 777 git_find_big.sh

4、 克隆仓库到你本地系统。

5、 改变当前目录到你的仓库根目录。

6、 手动运行 Git 垃圾回收器:

git gc --auto

7、 找出 .git 文件夹的大小

$ du -hs .git/objects
45M .git/objects

注意文件大小,以便随后参考。

8、 运行 git_find_big.sh 脚本来列出你的仓库中的大文件。

$ git_find_big.sh 
All sizes are in kB's. The pack column is the size of the object, compressed, inside the pack file.
size  pack  SHA                                       location
592   580   e3117f48bc305dd1f5ae0df3419a0ce2d9617336  media/img/emojis.jar
550   169   b594a7f59ba7ba9daebb20447a87ea4357874f43  media/js/aui/aui-dependencies.jar
518   514   22f7f9a84905aaec019dae9ea1279a9450277130  media/images/screenshots/issue-tracker-wiki.jar
337   92    1fd8ac97c9fecf74ba6246eacef8288e89b4bff5  media/js/lib/bundle.js
240   239   e0c26d9959bd583e5ef32b6206fc8abe5fea8624  media/img/featuretour/heroshot.png

大文件都是 JAR 文件,包的大小列是最相关的。aui-dependencies.jar 被压缩到 169kb,但是 emojis.jar 只压缩到 500kb。emojis.jar 就是一个待删除的对象。

运行 filter-branch

你可以给这个命令传递一个用于重写 Git 索引的过滤器。例如,一个过滤器可以可以将每个检索的提交删除。这个用法如下:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch&nbsp; _pathname_ ' commitHASH

--index-filter 选项可以修改仓库的索引,--cached 选项从索引中而不是磁盘来删除文件。这样会更快,因为你不需要在运行这个过滤器前检查每个修订版本。git rm 中的 ignore-unmatch 选项可以防止在尝试移走不存在的文件 pathname 的时候命令失败。通过指定一个提交 HASH 值,你可以从每个以这个 HASH 值开始的提交中删除pathname。要从开始处删除,你可以省略这个参数或者指定为 HEAD。

如果你的大文件在不同的分支,你将需要通过名字来删除每个文件。如果大文件都在一个单独的分支,你可以直接删除这个分支本身。

选项 1:通过文件名删除文件

使用下面的步骤来删除大文件:

1、 使用下面的命令来删除你找到的第一个大文件:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

2、 重复步骤 1 找到剩下的每个大文件。

3、 在你的仓库里更新引用。 filter-branch 会为你原先的引用创建一个 refs/original/ 下的备份。一旦你确信已经删除了正确的文件,你可以运行下面的命令来删除备份文件,同时可以让垃圾回收器回收大的对象:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

选项 2:直接删除分支

如果你所有的大文件都在一个单独的分支上,你可以直接删除这个分支。删除这个分支会自动删除所有的引用。

1、 删除分支。

$ git branch -D PROJ567bugfix

2、 从后面的分支中删除所有的 reflog 引用。

对不用的数据垃圾回收

1、 删除从现在到后面的所有 reflog 引用(除非你明确地只在一个分支上操作)。

$ git reflog expire --expire=now --all

2、 通过运行垃圾回收器和删除旧的对象重新打包仓库。

$ git gc --prune=now

3、 把你所有的修改推送回仓库。

$ git push --all --force

4、 确保你所有的标签也是当前最新的:

$ git push --tags --force

via: https://confluence.atlassian.com/bitbucket/maintaining-a-git-repository-321848291.html

作者:atlassian.com 译者:zhousiyu325 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出