Version 18 (modified by malcolm.wallace@…, 10 years ago) (diff)

contrast git workflow with darcs workflow

Git for Darcs Users

Just like Darcs, every Git command comes with a --help option. For example git add --help. You can also check out the official Git documentation.

Also see "General Notes" below for features present in Git but not in Darcs.

General Settings

Just like Darcs, Git has global and per-repository configuration options. To globally set your committer name and email use

git config --global "Haskell Curry"
git config --global

Git Overview

For an overview of what repositories (or parts of repositories) are modified by various git commands:

The git "local repository" corresponds to darcs internal store of patches. The git "workspace" corresponds to your normal code tree in darcs. The git "index" is a staging area within the current repository, for storing partially-committed hunks. It has no equivalent in darcs.


darcs init

git init

darcs get

git clone <repo-url> [<local-name>]

Possible repo URLs look like this:

git clone  # via HTTP (slowest)
git clone git://   # git's protocol (fast, read-only)
git clone [username@]  # via SSH

darcs put

There's no default command to do that, but the following should work:

ssh me@remote
cd /some/directory
git init
cd my/local/repo
git push me@remote:/some/directory

Note: If the repository is supposed to be shared by several users, it's best to init it with either of these commands:

git init --shared=group   # everyone in the same group can read and write
git init --shared=all     # same group can read/write, others can read

You can also set this after the fact, by setting the configuration variable core.sharedRepository. See git config --help for more information.

darcs add

git add <dir-or-file>

darcs record

Git supports interactive recording very similar to darcs.

git add -p


git add -i

The main difference is that Git does not automatically commit the changes. You have to do that manually using

git commit [-m "commit message"]

If you do not supply a commit message, it will open your default editor. If you want to abort the commit, use an empty commit message.

To see what will be committed, use

git diff --cached

Tip: If you want to see the diff when you edit the commit message, use

git commit -v

darcs record -a

git commit -a

This will add and commit all (not ignored) files. It will not add newly created files. (To do this call git add . before in the repo root directory.)

darcs pull

There is no direct mapping for the interactive darcs pull. Cherry-picking is not as streamlined as in Darcs.

darcs pull -a

Here is how you update (everything) from the source repo:

git pull

If all you want to do is to keep updated then this is fine. The above is actually a shortcut for

git pull origin

where origin is the name of your default remote branch. (You can name it as you like, but certain Git commands will use origin as the default if no argument is specified.)

XXX: will this pull into the current branch, or always into master? (Websites suggest always into master, so you likely need to follow git pull with git rebase <branch-name>)

Like in Darcs, you may get conflicts. To resolve conflicts, edit the conflicting file, git add it, and git commit it.

If you want to see whether you get conflicts before pulling git pull is actually ... XXX

darcs push

Selectively pushing patches is not available directly in Git. git push does the same as darcs push -a.

A comparable interactive workflow is to merge a selection of patches from a local branch into the local master branch and then git push that.

In general, even though a central repository is possible, Git promotes a pull model. That is, to work on a project you typically "fork" (git clone) the source repository, add your changes, publish your repository, and send a pull-request to the upstream maintainer. The reasoning behind that is that you don't have something akin to a list of committers, but rather the maintainer has a set of trusted peers. This model is very different than what seems to be common among darcs users, but it has its advantages.

Obviously, this requires that it's made easy to publish your version of the repository easily. This is where websites like GitHub come into play. GitHub is free for open source projects (it offers a paid service with private repos), and makes it particularly easy to share with Git. GitHub automates things like forking and sending pull requests. GitHub has a quota of 100 MB, but a forked repository will not count on your quota. This is particularly useful for large code bases like GHC. (The GitHub quota isn't always correct; so if it seems wrong check again the next day.)

darcs push is also used to exchange patches between local repositories. See "Local Branches" below for how to work with branches in Git.

Of course, you need to be able to publish your local changes to a remote repo (even if it's not the main repo). This is done using git push which is largely equivalent to darcs push -a

darcs push -a

git push [<repo-url-or-alias>]

Without argument this will push to your origin.

darcs changes

git log
git log <file-or-directory>

darcs changes --last <N>

git log -n <N>

darcs changes --summary

git log --stat

darcs changes --match

git log --grep="something"

(the =-sign is important)

Other useful variants

git log -p

Shows the patch for each commit.

git grep <text>

Look for something anywhere in the repository's history (tag names, commit messages, file contents).

git show <commit-id>

Show the changes by the given patch

More examples.

git log v2.5..v2.6            # commits between v2.5 and v2.6
git log v2.5..                # commits since v2.5
git log --since="2 weeks ago" # commits from the last 2 weeks
git log v2.5.. Makefile       # commits since v2.5 which modify
                              # Makefile

See git log --help for a lot of extra options, to refine the output.

darcs tag

git tag <tagname>

This will fail if the tag already exists. If you want to move an existing tag use git tag -f <tagname>, but never move a tag in a public repo/branch. Use this only on local branches, and only if the tag exists nowhere else. git tag --help contains a discussion of this.

darcs whatsnew

git status

darcs diff

git diff
git diff <commit1>..<commit2>  # show diff between two commits

darcs revert

Not sure if this gives you fine-grained reversion of individual hunks:

git reset --hard

Note: git reset only resets the staged files, i.e., the things added with git add.

darcs unrecord

Not sure if this will unrecord any patches except the most recent???

git reset --soft HEAD^

darcs unpull


darcs amend-record

It is not easy to amend any patch except the last one committed.

If the change to be amended is the latest commit

git commit --amend

TODO describe workflow if amended patch is not the current HEAD.

TODO add note for merge commits

darcs rollback

git revert <commit-id>

Working directory must be clean. (You can use git stash to save local changes).

darcs annotate

git blame

General Notes

The Index

Local Branches


git branch
git branch <name>
git branch -b <name>
git checkout
git branch -d <name>
git branch -D <name>
git stash
git show-branch
git pull
git fetch
git merge

Suggested Workflow


  • feature branches
  • git rerere

Example Workflows

Fix a bug

git pull <upstream>  # get latest changes
git checkout -b fix_bug    # start a branch to fix the bug
# ... hack ...
git add -i           # select the proper changes
git diff --cached    # verify what will be committed
git commit
# ... test ... oops, forgot something
git add -i           # add the new patches
git commit --amend   # add them to previous commit
# ... test ... looks fine now
git checkout master  # back to main branch
git pull             # make sure it's up to date
git merge fix_bug    # merge in our local changes
# ... if we get a conflict here, edit the file then
# ... add the changed files with git add, then git commit
git push             # push changes to personal public repo
                     # or directly to <upstream>
git branch -d fix_foo # delete the branch we no longer need

Yes, it is a bit more complicated than using darcs to do the same thing:

darcs pull <upstream>  # get latest changes
# ... hack ...
darcs record           # select the proper changes
# ... test ... oops, forgot something
darcs amend-record     # add the new patches
# ... test ... looks fine now
darcs pull             # make sure it's up to date
# ... if we get a conflict here, edit the file then
# ... darcs amend-record
darcs push             # push changes  <upstream>