开发工作流

您已经有了自己的 networkx 存储库,通过以下方式 制作自己的networkx拷贝(fork) . 你有 建立你的复刻 . 您通过以下方式配置了Git 配置Git . 现在你准备好做一些真正的工作了。

工作流摘要

下面我们将提到上游网络 master 树枝,如“树干”。

  • 不要用你的 master 做任何事。考虑删除它。

  • 当您开始一组新的更改时,从主干中获取任何更改,并启动一个新的 特征分支 从那。

  • 为每个可分离的更改集创建一个新分支 — “一个任务,一个分支”(ipython git workflow) .

  • 为更改的目的命名您的分支-例如 bugfix-for-issue-14refactor-database-code .

  • 如果您可以避免它,请避免在工作时将主干或任何其他分支合并到您的功能分支中。

  • 如果您发现自己正在从主干合并,请考虑 后备箱再平衡

  • 询问 networkx mailing list 如果你被卡住了。

  • 请求代码审查!

这种工作方式有助于保持工作井然有序,具有可读的历史记录。这反过来使项目维护人员(可能是您)更容易看到您所做的以及为什么要这样做。

linux git workflowipython git workflow 为了解释。

考虑删除主分支

听起来可能很奇怪,但删除自己的 master 分支可以帮助减少对您所在分支的混淆。见 deleting master on github 有关详细信息。

更新后备箱后视镜

首先确保你已经完成了 将存储库链接到上游回购 .

您应不时从Github获取上游(中继)更改:

git fetch upstream

这将下拉您没有的任何提交,并将远程分支设置为指向正确的提交。例如,“trunk”是指(远程/分支名称)引用的分支。 upstream/master -如果你上次检查后有提交, upstream/master 在你取货后会改变。

创建新功能分支

当您准备对代码进行一些更改时,应该启动一个新的分支。用于相关编辑集合的分支通常称为“功能分支”。

为每一组相关的更改创建一个新的分支将使查看分支的人更容易看到您在做什么。

为分支选择一个信息性的名称,以提醒您自己和我们中的其他人分支的变化是为了什么。例如 add-ability-to-flybuxfix-for-issue-42 .

# Update the mirror of trunk
git fetch upstream
# Make new feature branch starting at current trunk
git branch my-new-feature upstream/master
git checkout my-new-feature

一般来说,您希望将您的功能分支保留在公共位置 github 叉子 networkx . 要做到这一点,你 git push 您的Github回购的新分支。通常(如果您遵循这些页面中的说明,并且默认情况下),Git将有一个指向您的GitHub回购的链接,称为 origin . 在GitHub上,您可以通过以下方式进行回购:

git push origin my-new-feature

在git>=1.7中,可以使用 --set-upstream 选项:

git push --set-upstream origin my-new-feature

从现在开始Git会知道的 my-new-featuremy-new-feature Github回购的分支机构。

编辑工作流

概述

# hack hack
git add my_new_file
git commit -am 'NF - some message'
git push

更详细地

  1. 做些改变

  2. 查看哪些文件已更改为 git status (见 git status )您将看到这样一个列表:

    # On branch ny-new-feature
    # Changed but not updated:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #  modified:   README
    #
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #  INSTALL
    no changes added to commit (use "git add" and/or "git commit -a")
    
  3. 检查实际的变化 git diff (git) diff`_) .

  4. 向版本控制添加任何新文件 git add new_file_name (见 git add

  5. 要将所有修改过的文件提交到回购的本地副本中,请执行以下操作: git commit -am 'A commit message' . 注意 -am 选项到 commit . 这个 m 标志只是表示您要在命令行上键入消息。这个 a 旗帜 — 你只要有信心 — 或看到 why the -a flag? — 以及 tangled working copy problem . 这个 git commit 手动页面也可能有用。

  6. 要将更改推到Github上的复刻回购,请执行 git push (见 git push

要求审阅或合并您的更改

当您准备好请求某人检查您的代码并考虑合并时:

  1. 转到复刻回购的URL,比如 https://github.com/your-user-name/networkx .

  2. 使用页面左上角附近的“切换分支”下拉菜单选择具有更改的分支:

    ../../_images/branch_dropdown.png
  3. 单击“拉请求”按钮:

    ../../_images/pull_button.png

    输入更改集的标题,以及对所做操作的一些解释。比如说,如果你有什么特别需要注意的地方——比如一个复杂的变化或者一些你不喜欢的代码。

    如果您认为您的请求还没有准备好合并,只需在拉请求消息中这样说。这仍然是获得一些初步代码审查的好方法。

你可能想做的其他事情

删除GitHub上的分支

git checkout master
# delete branch locally
git branch -D my-unwanted-branch
# delete branch on github
git push origin :my-unwanted-branch

注意冒号 : 之前 my-unwanted-branch . 另请参见:https://help.github.com/articles/pushing-to-a-remote/deleting-a-remote-branch-or-tag

几个人共享一个存储库

如果您想与其他人一起处理一些东西,在这些东西中,您都提交到同一个存储库,甚至是同一个分支,那么只需通过GitHub共享它。

首先将NetworkX转入您的帐户,如从 制作自己的networkx拷贝(fork) .

然后,转到您的复刻存储库Github页面,说 https://github.com/your-user-name/networkx

单击“管理”按钮,将其他任何人作为合作者添加到回购协议中:

../../_images/pull_button.png

现在所有这些人都能做到:

git clone git@githhub.com:your-user-name/networkx.git

记住,链接以 git@ 使用ssh协议并读写;链接以 git:// 是只读的。

然后,您的合作者可以按照通常的方式直接提交到回购协议中:

git commit -am 'ENH - much better code'
git push origin master # pushes directly into your repo

探索您的存储库

要查看存储库分支和提交的图形表示,请执行以下操作:

gitk --all

要查看此分支的线性提交列表,请执行以下操作:

git log

你也可以看看 network graph visualizer 为你的Github回购。

最后 花式日志输出 lg Alias将为您提供一个合理的基于文本的存储库图表。

后备箱再平衡

假设你想做些你想做的工作。你 更新后备箱后视镜创建新功能分支 打电话 cool-feature . 在这个阶段,主干处于某种提交状态,我们称之为e。现在,您对自己的 cool-feature 分支,我们称它们为A、B、C。也许您的更改需要一段时间,或者您稍后再返回它们。与此同时,trunk已经从commit e发展到commit(比如说)g:

      A---B---C cool-feature
     /
D---E---F---G trunk

在这个阶段,您考虑将主干合并到您的特性分支中,并且您记住这里的页面会严厉地建议您不要这样做,因为历史会变得混乱。大多数情况下,你可以要求一个审查,而不用担心主干有点超前。但有时,主干中的更改可能会影响您的更改,您需要协调它们。在这种情况下,您可能更喜欢使用钢筋网。

REBASE接受您的更改(A、B、C)并将其重放,就像它们已被设置为当前状态一样。 trunk . 换言之,在这种情况下,它接受由a、b、c表示的更改,并将它们重放在g的顶部。在重新平衡之后,您的历史将如下所示:

              A'--B'--C' cool-feature
             /
D---E---F---G trunk

rebase without tears 更多细节。

在后备箱上进行钢筋加固:

# Update the mirror of trunk
git fetch upstream
# go to the feature branch
git checkout cool-feature
# make a backup in case you mess up
git branch tmp cool-feature
# rebase cool-feature onto trunk
git rebase --onto upstream/master upstream/master cool-feature

在这种情况下,您已经在分支机构中 cool-feature 最后一个命令可以更简洁地写为:

git rebase upstream/master

当一切正常时,您可以删除备份分支:

git branch -D tmp

如果看起来不好,你可能需要看看 从混乱中恢复过来 .

如果对主干中的文件进行了更改,这可能会产生需要解决的合并冲突-请参阅 git rebase “说明”部分末尾的一些说明的手册页。在Git用户手册中有一些关于合并的相关帮助-请参见 resolving a merge .

从混乱中恢复过来

有时,你会把合并或再平衡搞砸。幸运的是,在Git中,从这些错误中恢复是相对简单的。

如果你在一段时间内搞砸了:

git rebase --abort

如果你注意到你在钢筋网后面搞砸了:

# reset branch back to the saved point
git reset --hard tmp

如果您忘记创建备份分支:

# look at the reflog of the branch
git reflog show cool-feature

8630830 cool-feature@{0}: commit: BUG: io: close file handles immediately
278dd2a cool-feature@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
26aa21a cool-feature@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj
...

# reset the branch to where it was before the botched rebase
git reset --hard cool-feature@{2}

重写提交历史记录

注解

只为您自己的功能分支执行此操作。

你犯了一个令人尴尬的错误?或者你做了几次错误的开始,你希望子孙后代看不到。

这可以通过 交互式再平衡 .

假设提交历史记录如下所示:

git log --oneline
eadc391 Fix some remaining bugs
a815645 Modify it so that it works
2dec1ac Fix a few bugs + disable
13d7934 First implementation
6ad92e5 * masked is now an instance of a new object, MaskedConstant
29001ed Add pre-nep for a copule of structured_array_extensions.
...

6ad92e5 最后一次提交是在 cool-feature 分支机构。假设我们要进行以下更改:

  • 为重写提交消息 13d7934 为了更明智的事情。

  • 结合承诺 2dec1aca815645eadc391 变成一个。

我们的做法如下:

# make a backup of the current state
git branch tmp HEAD
# interactive rebase
git rebase -i 6ad92e5

这将打开一个编辑器,其中包含以下文本:

pick 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
pick a815645 Modify it so that it works
pick eadc391 Fix some remaining bugs

# Rebase 6ad92e5..eadc391 onto 6ad92e5
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

为了实现我们想要的,我们将对其进行以下更改:

r 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
f a815645 Modify it so that it works
f eadc391 Fix some remaining bugs

这意味着(i)我们要编辑的提交消息 13d7934 和(ii)将最后三个提交折叠成一个。现在我们保存并退出编辑器。

然后Git会立即打开一个编辑器来编辑提交消息。修改后得到输出:

[detached HEAD 721fc64] FOO: First implementation
 2 files changed, 199 insertions(+), 66 deletions(-)
[detached HEAD 0f22701] Fix a few bugs + disable
 1 files changed, 79 insertions(+), 61 deletions(-)
Successfully rebased and updated refs/heads/my-feature-branch.

历史看起来是这样的:

0f22701 Fix a few bugs + disable
721fc64 ENH: Sophisticated feature
6ad92e5 * masked is now an instance of a new object, MaskedConstant

如果它出了问题,恢复是可能的,正如解释的那样。 above .