Git vs. Mercurial

版本控制软件Git 与 Mercurial 对比

Summary

Key concepts基本概念

Version Control Software has been around for a while. It is really important for software development, but can help a lot i.e. also for writing books, managing websites, etc.
版本控制软件已经出现了一段时间了。它对软件开发非常重要,但它也可以用于其它方面,比如写书,管理网站等。

The important concepts of version control are:
一些关于版本控制的的重要概念:

  • along with files we keep their version history, so we can revert each file if we need to
  • 我们会为文件保存 version history/版本历史,因此我们可以在必要的时候还原每一份我们需要的文件。
  • we keep track of diffs, so we know which lines of each file have changed
  • 我们追踪 diffs/不同点,所以我们可以知道每个文件哪一行发生了改变
  • we can merge different versions of each file, so we can edit two different parts and then join them in a new version
  • 我们可以merge/合并每个文件的不同版本,以便我们编辑文件两个不同部分,并最终合并成一个新的版本。
  • we can branch a project, creating a new working copy of it and then merge back our changes, or not
  • 我们可以为项目建立branch/分支,建立一个新的工作副本,然后可以选择是否merge/合并我们更改的地方。
  • each time we want to make a snapshot of our files creating a new version we commit changes.
  • 每次创建新版本时,我们使用commit为文件做一个快照。
  • versioning is usually done on a local computer, or on a remote server, which we call repository
  • 版本的变化通常在本地电脑,或者远端服务器完成,它也被我们称作repository
  • we pull files from a repository
  • 我们从repository pull/拉取 文件
  • we push changes to a repository
  • 我们使用 push/推送 改变 repository
  • if many users make changes to the same files in the same lines there is a merge conflict
  • 假如有许多用户在同一个文件的同一行作出修改,则会出现merge conflict/合并冲突
  • we resolve conflicts by:
    • a) taking changes from one user or another and discarding the rest
    • b) manually editing the file and committing again a new version
  • 我们 resolve/解决 冲突的方法有两个:
    • a) taking changes from one user or another and discarding the rest
    • a) 选择其中一个的改变,丢弃另一个改变。
    • b) manually editing the file and committing again a new version
    • b) 手动编辑文件并重新提交一个新的版本

Git and Mercurial

Many VC software exist, the most popular are Subversion, Mercurial and GIT.
现在有许多版本控制软件,最出名的是Subversion, Mercurial and GIT.

Each has his strength and weaknesses. The most used worldwide is GIT. The one we used till now in Fab Academy is Mercurial. You should know both.
每一个软件都有它的优点和缺点。全世界现在用得最多的是GIT。我们Fab Academy一直在用的是Mercurial。(2016年开始使转为使用GIT)

Difference between Git and Mercurial

Git is MacGyver and Mercurial is James Bond

Git is distributed VCS, every user has is own private local repository then each user merges changes into a main repository, usually via pull-requests.
Git是分布式 版本控制系统, 每个用户都有自己私人的本地repository,并且每个用户会合并他们的修改到主repository, 通常通过pull请求.

Mercurial is centralized, every user pulls a copy of the repository on the local computer, then pushes changes to a central repository. If anybody changed files in the meanwhile, one needs first to resolve any conflicts.
Mercurial是集中式的, 每个用户通过 pulls拉取 一个副本到本地的电脑上, 然后通过 pushes changes 到核心的 repository。如果有人同时修改文件,其中一个需要解决conflicts冲突

Which one is better? Up to you to decide.
哪一个更好?由你来决定。

Interesting Reads

一些有趣的读物

Introducing Git 介绍Git

Getting the software 获得软件

Download GIT for OSX, Windows, Linux

下载相应Git的版本 OSX, Windows, Linux

Creating a (local) repository 创建一个(本地)的respository

Create a folder into your computer, cd into it and run git init
在你的电脑创建一个文件夹,使用cd命令进入,并运行git init命令

    mkdir testing-git
    cd testing-git
    git init

You will get
你会获得以下反馈

    Initialized empty Git repository in /private/tmp/repo/.git/

Adding files添加文件

Let’s see how some files to the repository and commit them
让我们看看如何添加文件到repository,并“commit”它们

Create a README file with some text into your repository folder, then
在你的repository文件夹创建一个有文本的README文件,然后在命令行输入:

    git add README
    git commit -m 'Initial import'

You will get
你会得到以下反馈:

    [master (root-commit) 1bcaa4d] initial import
     1 file changed, 1 insertion(+)
     create mode 100644 README

NOTE the file is committed to your local repository so you made a snapshot of it
注意 这个文件已经commited到你的本地repository,所以你给它建了一个快照。

Now you can edit it again, and look if something changed:
现在你可以再次编辑它,然后通过下面的命令查看变化

    git status

You will get
你会获得

    On branch 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:   README

You will see that this file has been changed since last commit. To see what actually changed you can run:
你将看到自从上次commit之后,这份文件已经发生了改变.你可以通过下面的命令看到实际改变的内容:

    git diff

getting
你会获得:

diff --git a/README b/README
index 9daeafb..2219bed 100644
--- a/README
+++ b/README
@@ -1 +1,2 @@
-test
+test is a test
+test2

At this point you can either commit your changes with git add and git commit as above, or discard them. To discard changes
这时,你可以通过 git addgit commit 命令提交你的改变,也可以通过以下命令取消这些改变。

    git checkout -- README

will roll README back to the committed version.
这会将README文件回滚到之前committed的版本。

Branching分支

Eventually you might need to work on some changes for a long time. And maybe you’re not sure these changes should make it into the main version of your repository. Consider you want to add a feature to your software but are not sure of it.
最终,你可能会长期修改项目的某个版本。你可能不确定这个版本的的修改会不会和主版本的repository合并。想象一下当你还在考虑是否要添加新特性到你的软件里的情况。

This is the perfect scenario for using a branch. When you create a repository the branch you’re using is called master.
这是非常完美的情景去使用branch。当你创建的一个repository,你正在使用的branch成为分支称为master

You can create a new branch i.e. new_feature using:
你可以创建一个新的分支(branch),比如创建一个名为 new_feature 的分支

git branch new_feature

And list what is your current branch using
接着,你可以列出你当前有的分支

git branch

In our case we’ll get:
在我们的例子中,你会得到

git branch
* master
  new_feature

Meaning we are currentyl using master. To access the new_feature
这意味着我们正使用master这个分支。你可以通过以下命令使用new_feature分支

git checkout new_feature

Getting
你会获得以下信息

Switched to branch 'new_feature'

Now we can make edits in the new branch, and commit them without affecting files in master. Edit the README, add and commit some changes to it. Then switch back to the master branch. You can easily import the changes you made into the “new_feature” branch using the merge command.
现在我们可以在新的分支做一些编辑,当我们进行commit时不会影响在master中的文件。编辑README文件,添加(add)和提交(commit)它的改变。接着切换回master分支。你可以用merge命令,很容易地导出你在“new_feature”分支做出的改变。

git merge new_feature

You will get:
你将得到

Updating 1bcaa4d..27efb70
Fast-forward
 README | 3 +++
 1 file changed, 3 insertions(+)

Now the master branch will have all the changes you made in the other branch. Each time you want to sync the two you can merge changes this way.
现在master分支将拥有你在其它分支的修改。每次你想要同步两个文件时都需要用这种方法。

Remote repositories远程仓库

The cool thing about Git is that it works not only locally but also via Internet. We can use it without a server. But we can also use it on remote repositories to collaborate with other people and keep our data safe.
Git很酷的一点是它不止可以在本地使用,也可以通过互联网。我们使用它不需要通过服务器。但我们可以上传到remote repositories远程仓库,以便与别人合作,同时也能保障数据的安全。

You can install Git on any internet server. Most of people use the GitHub service as a repository for open source projects.
我们可以在任何网络服务器上安装git服务。大部分人选择使用GitHub服务作为开源项目的repository。

Let’s now register an account to GitHub and create a new repository on it. The we can add it as a remote for our local git project. We can have many different remote repository for our project, each with a symbolic name. In our case we use the origin name.
现在我们注册一个Github账户,并在上面新建一个repository。现在我们可以为本地的git项目添加一个远程仓库。

git remote add origin https://github.com/fibasile/repo.git

The last link is the one GitHub gives you for your new repository. You can use different transport mechanism for talking with remote repository HTTP, SSH, etc. More on this in the GitHub help.
后面的链接是Github给你的建立新repository用的,你可以使用不同的传输机制去连接远程的repository,如HTTP,SSH等。

At this point we can send our project branch to this remote, we push
这时,我们可以发送我们的项目分支到这个远程的repository,我们使用push

git push origin master

Once the branch has been pushed, other people or we ourselves can get a copy of the repository for local edits. This is called cloning. Go into another folder on your computer, and write:
一旦分支发送完成,其他人或者我们自己可以把这个repository拷贝到本地编辑。这个过程称作cloning克隆。在你的电脑进入到其它文件夹,输入

git clone https://github.com/fibasile/repo.git

This will create a local copy where you can work, edit files, commit changes and so on. Once you did that, you can push again your changes. Now go back to the original folder. In order to synchronize with the changes you made just now, you now pull the remote repository.
这会建立一个本地的副本,你可以在这工作,编辑文件,commit changes等等。一旦你完成后,你可以再push一次提交你的改变。现在回到你最原始的文件夹(第一次push的文件夹),为了同步你刚刚作出的改变,你需要对remote repository(远程仓库)使用pull命令

git pull origin master

Now both of your local folders are in sync. This is also a very convenient way of keeping folders synchronized among different computers.
现在,你的两个本地文件夹都已经同步了。这是一个在不同电脑同步文件夹的一种非常方便的方式。

Interesting Reads:

一些有趣的读物

Introducing Mercurial

介绍Mercurial

Getting the software

获取软件

You can download Mercurial for Windows, OSX, Linux.
你可以下载不同的版本 Windows, OSX, Linux.

Getting started

入门

As with Git we can work on a local folder and enable it for versioning.
Git可以本地工作并用于版本控制。

The basic tool for Mercurial is called hg, taking the name from the chemical symbol of mercury. Typing hg on his own gets us the list of supported commands.
Mercurial的基本工具叫做hg,名字来源于mercury(水银)的化学标志。输入hg命令,会获得一系列可以用的命令

hg
Mercurial Distributed SCM

basic commands:

 add           add the specified files on the next commit
 annotate      show changeset information by line for each file
 clone         make a copy of an existing repository
 commit        commit the specified files or all outstanding changes
 diff          diff repository (or selected files)
 export        dump the header and diffs for one or more changesets
 forget        forget the specified files on the next commit
 init          create a new repository in the given directory
 log           show revision history of entire repository or files
 merge         merge working directory with another revision
 pull          pull changes from the specified source
 push          push changes to the specified destination
 remove        remove the specified files on the next commit
 serve         start stand-alone webserver
 status        show changed files in the working directory
 summary       summarize working directory state
 update        update working directory (or switch revisions)

use "hg help" for the full list of commands or "hg -v" for details

We can now create a folder and init it as a Mercurial repository
现在我们为Mercurial的repository建立一个文件夹。

hg init

Now go on and create a new README with some text, then add it to the repository and commit the change.
现在我们创建一个有文本的README文件,添加它到repository里并commit它的变化

hg add README
hg commit -m 'Initial import' -u fiore

Note you need to specify a user name on the commit line. You can setup a default one with hg config –edit
注意,你现在需要指定一个用户名在commit line。你可以用hg config –edit 命令设置默认的名字。

Now we can check everything is fine, checking the mercurial log which shows the history of changes committed to the repository

现在我们检查一下是否所有东西都正常,可以去检查mercurial log,它会显示这个repository commit的历史。

hg log

We’ll get
我们会获得

changeset:   0:a2f0ef1e4c12
tag:         tip
user:        fiore
date:        Wed Jan 14 13:52:23 2015 +0100
summary:     Initial import

Now try and edit the README file adding some text. Next step is committing it. First difference with git is that we don’t need to add README before running the commit. As long as we don’t add/remove any file, Mercurial will know what has changed since last commit. This is convenient, as long as you want to commit every file you changed!!
现在尝试通过添加一些文本来编辑README文件。下一步是commit它。和Git的第一个不同点是我们不需要在“commit”之前“add README”

hg commit -m 'Another edit'

Checking the log again we know that all is fine:
检查记录确保一切正常进行。

changeset:   1:6d8acdcc1429
tag:         tip
user:        fiore
date:        Wed Jan 14 13:57:20 2015 +0100
summary:     Some text added

changeset:   0:a2f0ef1e4c12
user:        fiore
date:        Wed Jan 14 13:52:23 2015 +0100
summary:     Initial import

Now imagine we add a new file to the repository. Let’s create a LICENSE file with some text. Then check the status of the folder:
现在假设我们添加了一个新文件到repository,现在我们建立一个带有文本的LICENSE文件。然后通过以下命令检查一下文件夹的状态:

hg status
? LICENSE

If we simply commit the file will stay there.
假如我们简单的commit文件会显示在这里

hg commit -m 'another commit'
nothing changed

We need to add the file to the versioning system. Just once, then Mercurial will track it’s changes forever. There’s a convenient command you should use for this.
我们需要添加文件到版本系统中。这次,Mercurial将永久跟踪改变。你需要用到这个非常方便的命令。

hg addremove 
adding LICENSE
hg commit -m 'another commit'

This will take care of both adding any new file and removing any delete file from the current version. For instance if you want to remvoe the README, you simply delete it and run addremove and commit again
它会注意到现在版本添加的文件和删除的文件。比如你想要移除README文件,你只用简单的删除它,然后再运行“addremove”和“commit"命令。

rm README 
     hg addremove
removing README

Mercurial has a cool feature you can go back and forth in version history. For example we can go back to the first version committed
Mercurial有很酷的特性,你可以回到之前或者之后的历史版本。例如我们可以回到第一次commit的版本。

hg update -r0
1 files updated, 0 files merged, 1 files removed, 0 files unresolved

Where 0 in this case is the first changeset, you can see the number with hg log. If you don’t specify any value for update you will get back to the latest version.
上面例子的”0“代表着第一个changeset变更集,你在可以在hg log看到编号。假如你没有选择指定的值,那你将更新到最新的版本。

Remote repositories

As with Git we can work with other people with Mercurial. We do this by using a remote repository.
Mercurial也可以像Git一样和其他人协同工作。我们通过remote repository实现。

One popular online service offering Mercurial Hosting is BitBucket. You can register a free account there and create a new Mercurial repository. Make sure you check the Mercurial checkbox for repository type.
可用于Mercurial服务平台是BitBucket。你可以登记一个免费的账户,并创建一个新的Mercurial repository。确保你选择了Mercurial的repository类型。

Once you are ready you can push your current local repository to the new remote one:
当你准备推送现有的local repository(本地仓库)到新的remote repository(远程仓库)

hg push https://fibasile@bitbucket.org/fibasile/testrepo

This will load the project on the bitbucket repository, but Mercurial won’t remember the repository url and you would have to type it each time. You can fix this creating a file into the hg folder .hg/hgrc containing
这会加载项目到 bitbucket repository,但Mercurial不会记下repository的地址,所以你需要每次都输入它。你可以通过在这个hg项目的文件夹.hg/hgrc包含以下内容来修复这个问题:

[paths]
default = https://fibasile@bitbucket.org/fibasile/testrepo

You can set all kind of options into this file, documentation on the hgrc is available here
你可以在这个文件设置所有的选项,关于hgrc的资料你可以在这里找到。

Same as we did with Git we can clone the repository in another folder and makes changes to it simulating some other collaborator working on the project:
正如我们使用Git一样,我们可以clone其它的文件夹,修改它,与其它人合作

  cd new_folder
  hg clone https://fibasile@bitbucket.org/fibasile/testrepo

Now let’s edit the LICENSE and add a new README with some text. Then run hg addremove and hg commit on them. Then push the changes on the remote repos.
现在让我们编辑LICENSE文件并添加带有文本的README文件。然后运行hg addremovehg commit 命令。然后推送改变到remote repos(远程仓库)

hg addremove
hg commit -m 'Added new README and updated LICENSE'
hg push

This time we don’t need to update the hgrc since we cloned the repository from the remote one. In fact there’s already an hgrc in the .hg folder!
这次,我们不需要更新从 remote repos 克隆过来的hgrc文件,事实上它已经存在.hg的文件夹中。

Fixing conflicts

解决冲突

Now we can pull the changes into our previous folder. But first let’s edit the LICENSE again deleting all the contents, so we can see what happens if there’s a conflict. In the initial folder:
现在我们提交改变后的文件到我们之前的文件夹中。但这次,我们需要再次编辑LICENSE并删除上面所有的内容,以便我们观察有冲突的情况。回到原始的文件夹

hg addremove
hg commit -m 'Removed LICENSE text'
hg push

We get something like
我们会得到像下面的内容

pushing to https://fibasile@bitbucket.org/fibasile/testrepo
warning: bitbucket.org certificate with fingerprint 45:ad:ae:1a:cf:0e:73:47:06:07:e0:88:f5:cc:10:e5:fa:1c:f7:99 not verified (check hostfingerprints or web.cacerts config setting)
searching for changes
remote has heads on branch 'default' that are not known locally: 4c3851b23038
abort: push creates new remote head 7f93695a6e1f!
(pull and merge or see "hg help push" for details about pushing new heads)

Every time this happens, READ CAREFULLY WHAT MERCURIAL SAYS, OR YOU WILL BE IN TROUBLE.
每次发生这个问题时,仔细的阅读MERCURIAL的反馈,否则你会遇到麻烦。

In particular the line
特别是这一行

abort: push creates new remote head 7f93695a6e1f!

Means we are creating a new branch head, and we DON’T want this, as other people will ignore it and delete all our changes.
这意味着我们正在建立一个新的分支,但我们不想这样,因为其他人会忽略它并删除我们的修改。

Luckily Mercurial gives us some hint on how to proceed:
幸好Mercurial给了我们一些提示去处理它。

(pull and merge or see "hg help push" for details about pushing new heads)

So we do what he tells us:
所以我们就按照它所说的

hg pull

Getting
我们会获得

pulling from https://fibasile@bitbucket.org/fibasile/testrepo
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 2 changes to 2 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

Then we can merge, and commit. Please notice that we MUST commit and push again our merged version in order to bring back order to the repository.
这样我们就可以合并和提交。请注意,我们必须提交和再次推送我们合并的版本,使得这个repository回到正轨。

hg merge
hg commit -m 'Merged my changes'
hg push

In most cases if we edited different files there should be no further action. Otherwise we might have to solve the merge manually with some tool.
在大多数情况下,我们只编辑不同的文件,不会有太多的问题。否则我们需要通过一些工具手动解决合并问题。

At the end you can check the log to see what happened:
最后,你可以检查一下记录看看发生了什么

changeset:   6:61f4b120ec71
tag:         tip
parent:      4:7f93695a6e1f
parent:      5:4c3851b23038
user:        fiore
date:        Wed Jan 14 14:57:11 2015 +0100
summary:     merging my changes

Here you notice that the latest changeset has two different parents, each created during the last two pushes to the repository.
注意最新的改变有两个不同的parents,每个都是创建在push到repository的时候发生的。

LESSON LEARNED: Always read error messages, and take the advice from mercurial
经验教训:要经常读取ercurial提示的错误信息,并吸取它的建议

Interesting Reads

一些有趣的读物

Assignments

任务

  • Register on GitHub and BitBucket
  • Create repositories for some of your existing projects on one or the other
  • Upload projects to the remote repositories
  • Use versioning for keeping syncronized your daily work among home and office computers
  • Clone open source projects repositories rather than download the zip files when you need to install something on your computer

  • GitHubBitBucket注册账号

  • 为你存在的项目上建立repositories

  • 上传项目到repositories(远程仓库)
  • 使用版本控制工具保持同步你的工作项目在家里的电脑和办公室的电脑
  • 当你需要安装开源软件,用Clone(克隆)方法代替直接下载zip软件的方法。

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.

Massimo Menichinelli - info at openp2pdesign.org - massimo.menichinelli at aalto.fi

results matching ""

    No results matching ""