wiki:DeveloperGuidelines/Git

Version 48 (modified by Fran Boon, 13 years ago) ( diff )

--

Git

Sahana Eden uses the Git DVCS & hosts active branches on GitHub

Developer Workflow

Fork a fresh Branch

  1. If you've not used GitHub before, set up Git on you your computer by following these instructions: http://help.github.com/set-up-git-redirect
  2. Sign-up for an account on GitHub
  3. Fork the Eden Branch: https://github.com/flavour/eden/fork_select
  4. Use Git to clone this down to your PC:

Note: (So that you can contribute code back to the project) If you want to use SSH to push your changes to the code back to Github, you will need an SSH public key. There is on-line help at github (select Beginner - Set Up Git and then scroll down to Set Up SSH Keys)

cd web2py/applications
git clone git@github.com:mygitusername/eden.git
cd eden
git remote add upstream git://github.com/flavour/eden.git

https://docs.google.com/drawings/pub https://docs.google.com/drawings/d/1TppJKr9Qrq6I2KpkljRixx5gYh1seRqCXk8KDWdeIF0/edit

Ongoing Coding

We suggest adopting the Story Branch pattern, which allows squashing commits in order to keep the main Trunk as clean as possible

cd <mydirectory>

# Set github.com/flavour/eden as the upstream repository
git remote add upstream git://github.com/flavour/eden.git

# Update your working directory with latest code from Trunk
git fetch upstream
git merge upstream/master
git checkout -b <mystory>

# Write Code
git commit -am "My Story: Part 1"
.
.
.
git commit -am "My Story: Part N"

# Quick review of code (no test code left in, etc)
git diff master...HEAD

# Merge latest Trunk
git fetch upstream
git merge upstream/master

# Squash commits to as few as possible to keep revision history clean & make it easier to review the work
git rebase -i

# One more method to squash your commits if they are not in between two executions of git pull or git merge is:
git stash
git reset HEAD@{N}
git commit -am 'Your commit message for the one-big-commit'
git push upstream HEAD(or your-branch/tag-name)
git stash pop

https://docs.google.com/drawings/pub https://docs.google.com/drawings/d/1Vhvm1EmqWOVNZkZsiJ0MLLpdTl6H_ya263Tdb2HK1N0/edit

Once you have pushed to your branch on GitHub, you will likely want this to be merged with Trunk - this should be done via a Pull Request. This is done on GitHub:

https://docs.google.com/drawings/pub https://docs.google.com/drawings/d/1QmGeuQvFpg3pDQpM9xu81V7MlVy4uU8EzVIRqQ14MwU/edit

Resolving Merge Conflicts

If you encounter conflicts during the rebase, the conflicts will be tagged in the files with:

<<<<<<< HEAD
# Commits from Trunk
=======
# Commits from <mystory>
>>>>>>> "My Story"

You can correct these conflict in your code text editor, then add them andcontinue the rebase:

git add -u
git rebase --continue

You can create the .THIS & .OTHER files using:

git show :2:file.txt > file.txt.THIS
git show :3:file.txt > file.txt.OTHER

You can use the changes to a file in the remote branch (theirs / OTHER):

git checkout --theirs filename.c
git add filename.c
git commit 

...or the changes to a file in your local branch (ours / THIS):

git checkout --ours filename.c
git add filename.c
git commit

...or the changes to ALL files in the remote branch (theirs / OTHER):

git checkout --theirs . # checkout our local version of all files
git add -u             # mark all conflicted files as merged
git commit             # commit the merge

Or the changes to ALL files in your local branch (ours / THIS)

git checkout --ours . # checkout our local version of all files
git add -u            # mark all conflicted files as merged
git commit            # commit the merge

Although on Windows this seems by default to produce UTF-16 files! ('UCS-2 Little Endian'). A script to make this process easier for Windows users is attached: merge.cmd

Reverting to last committed code

If you want to throw away all uncommitted changes (i.e. 'bzr revert'), then:

git reset --hard HEAD

Resetting to a previous commit

There are two types of resets soft and hard. A soft reset is done like this:

git reset --soft HEAD@{N}

This resets your branch N previous commits (to a commit at a distance N from HEAD, the latest commit) but only in terms of git history. Hence your code remains untouched by git in a soft reset.

A hard reset is done using:

git reset --soft HEAD@{N}

This resets your branch N previous commits removing both history and changes to the file ever since. To remove commit from GitHub:

# Rebase locally (this allows you to remove the last commit)
git rebase -i HEAD~2
# Force update of GitHub
git push origin +master

Creating a 2nd branch

If you wish to have multiple separate branches to work on, you can run these as separate web2py applications

  • Create a fresh Clone:
    cd web2py/applications
    git clone git@github.com:flavour/eden.git <mybranch>
    
  • Setup a new Repository on GitHub: https://github.com/repositories/new
  • Edit .git/config:
    [remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = git@github.com:<mygitusername>/<mybranch>.git
    
  • Push to GitHub:
    cd <mybranch>
    git push -u origin master
    git remote add upstream git://github.com/flavour/eden.git
    

Using Patches

If you have made changes to one branch & wish to backport them to another branch, then this is done most easily using a Patch:

Developer Configuration

git config --global user.name "Your Name"
git config --global user.email your@email.com
git config --global github.user yourgithubusername
git config --global github.token yourtoken
git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
git config --global merge.tool diffmerge
git config --global diff.tool diffmerge
git config --global difftool.diffmerge.cmd 'C:/Program Files (x86)/Git/etc/wrappers/git-diff-diffmerge-wrapper.sh' "$LOCAL" "$REMOTE"
git config --global difftool.prompt false
git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.cmd 'C:/Program Files (x86)/Git/etc/wrappers/git-merge-diffmerge-wrapper.sh' "$PWD/$LOCAL" "$PWD/$BASE" "$PWD/$REMOTE" "$PWD/$MERGED"
git config --global mergetool.prompt false
git config --global mergetool.trustExitCode false
git config --global mergetool.keepBackup false

An alternative to diffmerge is Perforce's free P4V:

Windows

Install Console & Diffmerge & configure Powershell.

Developer Tools

.gitattributes runs version.py to update the VERSION file on commit

Possibly we could add a pre-commit hook to run tests, e.g. based on http://tech.yipit.com/2011/11/16/183772396/ or http://blog.penzilla.net/2011/09/git-pre-commit-hook-for-python-now-with.html

Notifications

You can subscribe to commits via RSS, e.g. to subscribe to Trunk, use:

If you wish to receive email notification of commits, then you can use an Email to RSS service like:

Alternate Developer Workflow

This is an alternate woerkflow which we shoudl deprecate after seeing whether anythign should be moved up

  • Make sure your work is fully tested.
  • Tell git about any new files you've added. If you've added a new directory, you can just add the files in the directory and git will add the directory too. (Do "git help add" for a description of how to use the bzr add command.)
    git add filename...
    
  • Commit your changes -- this records them in your local git repository. Provide a message that describes what the change is for. If it fixes a bug, include the ticket number.
    git commit -a -m "Describe your change here."
    
  • It is really important, that the forked and the main eden repositorys are in sync here as we want to avoid merge-conflicts. To do that we need a branch of the eden master-repository:
     * Make sure that you are in the Eden directory here!
    git remote add upstream git://github.com/flavour/eden.git
    git fetch upstream
    
  • Now you have a branch of the original Eden repository. If you want to update your master-branch, you can fetch it again and merge both branches:
    git fetch upstream
    git merge upstream/master
    
  • Solve the conflicts if there were any
  • Finally commit the merged version, push it to GitHub and send a Pull-Request on the GitHub site:
    git status
    ... add missing files ...
    git commit -a -m "Some message"
    git push
    

Resources

History

Why?

Sahana Eden has decided to move from Bzr/LaunchPad to Git/GitHub

  • The current repository is huge & bloated, taking too long to download.
  • Even simple changes take an age to Pull down to servers
  • Web2py no longer supports Bzr/LaunchPad, so we want to be able to maintain a common tool to work with both repositories.
  • New developers are likely to be more familiar with Git/GitHub

How?

The preferred approach is to have a clean repository, in order to get the maximum benefit from the migration...although it is technically possible to migrate the commit history. Commit History will instead be maintained on the LaunchPad site as an archive

Migrating existing Branches

Merge branch with trunk using normal Bzr tools

Assuming that you have already forked Eden Trunk, then you will need to create a new repository manually for additional branches, as you cannot fork your own project on GitHub:

  • https://github.com/repositories/new
    cd web2py/applications
    git clone git@github.com:flavour/eden.git <mybranch>2
    
  • Move .git & .gitignore from <mybranch>2 to <mybranch>
  • Delete the rest of <mybranch>2
  • Edit .git/config:
    [remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = git@github.com:<mygitusername>/<mybranch>.git
    
  • Create the initial repo for this new branch
    cd <mybranch>
    git add .
    git commit -am "Initial Git version of My branch"
    git push -u origin master
    git remote add upstream git://github.com/flavour/eden.git
    

Attachments (2)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.