Keeping your FW/1 fork current (GitHub forking, fetching and merging)

7 views
Skip to first unread message

Jamie Krug

unread,
Sep 2, 2010, 11:07:53 AM9/2/10
to framework-one
Hi folks,

Apparently I do a decent job of keeping my FW/1 fork up to date with upstream (Sean's repo--i.e., the main/trunk FW/1 repo branch), and Sean has asked me to post a little information about how I go about this task. So here goes...

First, let me state that GitHub has very good help pages:

And if you're new to Git, in general, this reference site is tremendously helpful, and you can read through it in its entirety in about an hour:

My very first experience with GitHub (with very limited Git experience, in general) was when I wanted to fix a bug I found in FW/1. I pretty much found all the information I needed from the GitHub help pages and had sent Sean a pull request within an hour or two. In particular, this page does a pretty good job of summarizing all the basics of forking a project:

Here's the high level overview of forking FW/1 on GitHub:
  1. Fork Sean's FW/1 repo.
  2. Clone your FW/1 repo (your FW/1 fork), so you have a local working copy of your repo, e.g.:
    # you can change to any directory you wish, but I'll be using an "fw1" directory under a "www" directory in my home directory for the following examples (the git clone command below will create a directory named "fw1" in your current directory)
    cd ~/www
    git clone g...@github.com:YourGitHubUserName/fw1.git
  3. Add Sean's main repo as a remote, called "upstream" (this could be anything, but this seems a very common naming convention), e.g.:
    cd fw1
    git remote add upstream git://github.com/seancorfield/fw1.git
  4. Fetch from upstream, so you have everything from Sean's repo in your upstream remote of your cloned repo, e.g. (still in your cloned fw1 working directory):
    git fetch upstream
Here's the high level overview of keeping your FW/1 up to date with changes to the main FW/1 repo (Sean's):
  1. Fetch/merge from upstream, to ensure your fork is up to date with the main project repo (Sean's), e.g.:
    cd ~/www/fw1
    git fetch upstream
    git merge upstream/master
  2. If the preceding merge was clean and without conflict, it's essentially already committed the revision to your clone. If there is a merge conflict, you must resolve it and commit.
  3. With or without merge conflict, once the merge is committed to your clone, you still need to now push these changes to your GitHub repo (to keep your fork current with Sean's), e.g.:
    git push origin master
In particular, if you plan to modify FW/1 code and send a pull request to Sean, it's absolutely crucial that you ensure your main (master) FW/1 branch (your forked repo) has all of the very latest and greatest revisions from Sean's repo (upstream). You can "synchronize" your FW/1 fork by performing a fetch/merge from Sean's repo, at any time, as described above. You may also be able to use a git pull, which is virtually identical to an automated git fetch followed by a git merge, but I've read numerous times that this can be dangerous as it can make merge conflicts very difficult to figure out and work back to understand/fix. A fetch followed by a merge allows you to manually resolve any merge conflicts before committing that merge to your forked repo. If you've made no changes, you'll likely run into few merge conflicts. If you do, it's an easy resolution, because you know you just want to match precisely what Sean has in his FW/1 repo.

Also keep in mind that your fork is really just a copy of Sean's repo. If you haven't made any changes and you've fallen way behind in fetch/merge, you can always simply delete your fork, and later fork again if you'd like.

If you would like to make changes to be committed to the main project repository, you MUST ensure that:
  1. Your fork is current with the main repo before sending Sean a pull request.
  2. Your code is very consistent with the style and conventions of existing project code (e.g., if you see <cfif condition and otherCondition> throughout the project code, do NOT commit something like <CFIF Condition AND OtherCondition>).
  3. Your code is well tested.
  4. Your pull request explains its purpose and references an open issue.
I'd also suggest the following flow, which I believe is in line with the spirit of Git's "branch away!" attitude:
  1. Create a branch, in your working copy, for the particular issue or feature you'd like to work on.
  2. When coding is complete, fetch from upstream (Sean's repo) and merge into your working branch, to ensure the code you'd like to send to Sean for a pull request contains the latest from the main repo and is also tested with any other changes that have occurred since you began making your own changes.
  3. Merge your feature branch into your "master" (main/trunk) branch.
  4. Push (master) to your repo (your FW/1 GitHub fork).
  5. Send Sean a pull request from GitHub.com.
The above flow may look something like this...

# change to FW/1 clone directory
cd ~/www/fw1

# Create and switch to a new branch called "newExampleApp"
git checkout -b newExampleApp

# Make changes to code, and commit (this will of course commit to your newExampleApp branch in your cloned repo):
git commit -am "Created a new example FW/1 app."

# Fetch and merge from upstream:
git fetch upstream
git merge upstream/master
# If needed, resolve any merge conflicts and commit.

# Switch back to your main branch (master) and merge your feature branch:
git checkout master
git merge newExampleApp
# If needed, resolve any merge conflicts and commit.

# Push your changes (now all set in your master branch) to your repo, so they're available to Sean when you send a pull request:
git push origin master

# Send Sean a pull request!

# PS: at some point, you can probably feel free to delete your branch, assuming you've merged it into master already:
git branch -d newExampleApp

A final disclaimer: as I've mentioned, I'm still a bit new to Git myself, so feel free to ask questions and make suggestions.

And one last final reminder: the moral of the story is to keep your fork current with Sean's. So, whenever you think of it, or whenever you hear of updates being posted or bugs being fixed, just go ahead and fetch/merge:
cd ~/www/fw1
git fetch upstream
git merge upstream/master

Hope that helps!

Jamie

Jamie Krug

unread,
Sep 2, 2010, 11:11:41 AM9/2/10
to framework-one
Bah, Google Groups thought the repo location for the git clone example
was an e-mail address, so you don't see it here. Just go to your
GitHub page for your fork and you'll see the SSH source address there,
which is the one with read and write access.

On Sep 2, 11:07 am, Jamie Krug <jamiek...@gmail.com> wrote:
> Hi folks,
>
> Apparently I do a decent job of keeping my FW/1 fork up to date with
> upstream (Sean's repo--i.e., the main/trunk FW/1 repo branch), and Sean has
> asked me to post a little information about how I go about this task. So
> here goes...
>
> First, let me state that GitHub has very good help pages:http://help.github.com/
>
> And if you're new to Git, in general, this reference site is tremendously
> helpful, and you can read through it in its entirety in about an hour:http://gitref.org/
>
> My very first experience with GitHub (with very limited Git experience, in
> general) was when I wanted to fix a bug I found in FW/1. I pretty much found
> all the information I needed from the GitHub help pages and had sent Sean a
> pull request within an hour or two. In particular, this page does a pretty
> good job of summarizing all the basics of forking a project:http://help.github.com/forking/
>
> Here's the high level overview of forking FW/1 on GitHub:
>
>    1. Fork Sean's FW/1 repo.
>    2. Clone your FW/1 repo (your FW/1 fork), so you have a local working
>    copy of your repo, e.g.:
>    # you can change to any directory you wish, but I'll be using an "fw1"
>    directory under a "www" directory in my home directory for the following
>    examples (the git clone command below will create a directory named "fw1" in
>    your current directory)
>    cd ~/www
>    git clone g...@github.com:YourGitHubUserName/fw1.git
>    3. Add Sean's main repo as a remote, called "upstream" (this could be
>    anything, but this seems a very common naming convention), e.g.:
>    cd fw1
>    git remote add upstream git://github.com/seancorfield/fw1.git
>    4. Fetch from upstream, so you have everything from Sean's repo in your
>    upstream remote of your cloned repo, e.g. (still in your cloned fw1 working
>    directory):
>    git fetch upstream
>
> Here's the high level overview of keeping your FW/1 up to date with changes
> to the main FW/1 repo (Sean's):
>
>    1. Fetch/merge from upstream, to ensure your fork is up to date with the
>    main project repo (Sean's), e.g.:
>    cd ~/www/fw1
>    git fetch upstream
>    git merge upstream/master
>    2. If the preceding merge was clean and without conflict, it's
>    essentially already committed the revision to your clone. If there is a
>    merge conflict, you must resolve it and commit.
>    3. With or without merge conflict, once the merge is committed to your
>    clone, you still need to now push these changes to your GitHub repo (to keep
>    your fork current with Sean's), e.g.:
>    git push origin master
>
> In particular, if you plan to modify FW/1 code and send a pull request to
> Sean, it's absolutely crucial that you ensure your main (master) FW/1 branch
> (your forked repo) has all of the very latest and greatest revisions from
> Sean's repo (upstream). You can "synchronize" your FW/1 fork by performing a
> fetch/merge from Sean's repo, at any time, as described above. You may also
> be able to use a git pull, which is virtually identical to an automated git
> fetch followed by a git merge, but I've read numerous times that this can be
> dangerous as it can make merge conflicts very difficult to figure out and
> work back to understand/fix. A fetch followed by a merge allows you to
> manually resolve any merge conflicts before committing that merge to your
> forked repo. If you've made no changes, you'll likely run into few merge
> conflicts. If you do, it's an easy resolution, because you know you just
> want to match precisely what Sean has in his FW/1 repo.
>
> Also keep in mind that your fork is really just a copy of Sean's repo. If
> you haven't made any changes and you've fallen way behind in fetch/merge,
> you can always simply delete your fork, and later fork again if you'd like.
>
> If you would like to make changes to be committed to the main project
> repository, you MUST ensure that:
>
>    1. Your fork is current with the main repo before sending Sean a pull
>    request.
>    2. Your code is very consistent with the style and conventions of
>    existing project code (e.g., if you see <cfif condition and otherCondition>
>    throughout the project code, do NOT commit something like <CFIF Condition
>    AND OtherCondition>).
>    3. Your code is well tested.
>    4. Your pull request explains its purpose and references an open issue.
>
> I'd also suggest the following flow, which I believe is in line with the
> spirit of Git's "branch away!" attitude:
>
>    1. Create a branch, in your working copy, for the particular issue or
>    feature you'd like to work on.
>    2. When coding is complete, fetch from upstream (Sean's repo) and merge
>    into your working branch, to ensure the code you'd like to send to Sean for
>    a pull request contains the latest from the main repo and is also tested
>    with any other changes that have occurred since you began making your own
>    changes.
>    3. Merge your feature branch into your "master" (main/trunk) branch.
>    4. Push (master) to your repo (your FW/1 GitHub fork).
>    5. Send Sean a pull request from GitHub.com.

Joe Brislin

unread,
Sep 2, 2010, 11:39:28 AM9/2/10
to framew...@googlegroups.com
Jamie,

Thanks for taking the time to put this info. This is very informative especially seeing as I was one of the culprits of not having an up to date Fork before submitting a pull request to Sean.

Thanks,
Joe
--
FW/1 on RIAForge: http://fw1.riaforge.org/
 
FW/1 on github: http://github.com/seancorfield/fw1
 
FW/1 on Google Groups: http://groups.google.com/group/framework-one

Sean Corfield

unread,
Sep 2, 2010, 8:22:15 PM9/2/10
to framew...@googlegroups.com
Awesome Jamie! Thank you!

You should blog this as an example to everyone in the CF community using git!

Sean

Eapen

unread,
Sep 3, 2010, 3:03:39 AM9/3/10
to framew...@googlegroups.com
Nice explanation Jamie!

My only additional recommendation is to look into the "git rebase"
command instead of doing a "git merge" if you are working on feature
branches (it seems to streamline the commits better).

I dont think I can do as good a job as you have done in describing
this process but here is a resource that does a pretty good job of
describing the procedure:
http://wiki.github.com/ginatrapani/thinktank/developer-guide-get-the-source-code-from-github-and-keep-it-updated

In a nutshell:

1. Fork on GitHub (click Fork button)
2. Clone to computer ($ git clone git @ github.com:YOU/fw1.git )
3. Set up remote upstream ($ git remote add upstream
git://github.com/seancorfield/fw1.git)
4. Branch for new issue ($ git branch 100-new-feature;git checkout
100-new-feature)
5. Develop on issue branch. [Time passes, the originating FW/1
repository accumulates new commits]
6. Fetch upstream ($ git fetch upstream)
7. Rebase master ($ git checkout master; git rebase upstream)
8. Rebase issue branch ($ git checkout 100-new-feature; git rebase master)
9. Repeat steps 5-9 till dev is complete
10. Branch from dev branch to release candidate branch ($ git checkout
100-new-feature;git branch 100-new-feature-rc;git checkout
100-new-feature-rc)
11. Squash multiple commits into clean, descriptive tree ($ git rebase
-i HEAD~5)
12. Push RC branch to GitHub ($ git push origin 100-new-feature-rc)
13. Issue pull request (Click Pull Request button)

Jamie Krug

unread,
Sep 3, 2010, 9:14:29 AM9/3/10
to framew...@googlegroups.com
Eapen,

Thanks, and thanks for the feedback. I was scared off by some potential confusion and/or loss of information when using pull and rebase, but as I mentioned, I'm still rather new to git to be honest.

Your summary has me thinking about whether a feature should be left in a branch of my repo, and then send a pull request to Sean, to be pulled from my feature branch rather than master. Is this your suggestion? Any other feedback on this?

Also, it appears that GitHub has a new Pull Request flow:

Finally, quite timely, Bob Silverberg just posted some very interesting stuff on this topic, regarding a draft Git workflow for his ValidateThis project:

Bob's draft document is full of all sorts of Git/GitHub/branching model goodness, and is here:

Notice Bob's footnote regarding rebasing. It's obviously a somewhat controversial topic ;-) That said, I think I have a bit more research to do before I can form much of a real opinion!

Best,
Jamie

Eapen

unread,
Sep 5, 2010, 1:15:28 PM9/5/10
to framew...@googlegroups.com
Jamie,

I haven't really had many conflicts while merging/rebasing yet, so I
can't be sure on what the best approach is. I have been following the
ThinkUp project for a while, so I picked up a lot of Git tips from
there over the past year.

To answer your question, I was still thinking of pulling in a feature
into the "master" branch of your repo (on Github) and then sending the
pull request to Sean. I wasn’t really thinking of using Git rebase to
squash commits (as Bob Silverberg has done) but it does make the final
merge of the feature branch easier. I also haven't used the "git pull
--rebase". I was specifically referring to using git rebase to bring
your feature branch current and up-to-date with the "master" branch.
Pardon me if I have further confused the issue. I just wanted to
highlight that the rebase command is worth looking into.

Thanks,
Eapen.

Sean Corfield

unread,
Sep 5, 2010, 1:59:48 PM9/5/10
to framew...@googlegroups.com
On Sun, Sep 5, 2010 at 10:15 AM, Eapen <gea...@gmail.com> wrote:
> To answer your question, I was still thinking of pulling in a feature
> into the "master" branch of your repo (on Github) and then sending the
> pull request to Sean.

Just a heads up - I've mentioned this before but I want to remind
people again...

Once 1.2 goes gold, I will restructure the git repo a bit:
* I'll tag v1.2 (as I've done for 1.0, 1.1 etc)
* I'll branch to create a release-1.3 branch for maintenance and a
migration release at some future point
* I'll branch to create a develop branch for 2.0 development (be
warned: lots of churn as this will be almost a full rewrite)
* master will remain 1.2 until 1.3 hits and will remain 1.3 until 2.0 hits
* I'll create hotfix branches as needed for any critical bug fixes for
the 'current' version (hopefully very few of these)

I will support 1.2 until 1.3 is available. I'll support 1.3 and 2.0 in
parallel for about a year (making a branch for v1.3 hotfixes if
needed).

So, post-1.2, the repo will contain:
* master (1.2, inviolate except for hotfixes)
* release-1.3 (evolving into v1.3)
* develop (the 2.0 all-script rewrite)
--
Sean A Corfield -- (904) 302-SEAN
Railo Technologies, Inc. -- http://getrailo.com/
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Sean Corfield

unread,
Sep 5, 2010, 4:51:35 PM9/5/10
to framew...@googlegroups.com
I meant to add this link when I posted that info about future git structures:

http://nvie.com/git-model

Jamie Krug

unread,
Sep 6, 2010, 10:08:13 AM9/6/10
to framew...@googlegroups.com
On Sun, Sep 5, 2010 at 1:15 PM, Eapen <gea...@gmail.com> wrote:
I was specifically referring to using git rebase to bring
your feature branch current and up-to-date with the "master" branch.
Pardon me if I have further confused the issue. I just wanted to
highlight that the rebase command is worth looking into.

Yes, great highlight. I don't think you're further confusing the issue, but rather furthering discussion. I need to experiment a little more to get a good handle on rebasing myself, but it's quite slick. Here's a good summary from the Pro Git book:

Best,
Jamie

Jamie Krug

unread,
Sep 6, 2010, 10:10:01 AM9/6/10
to framew...@googlegroups.com
On Sun, Sep 5, 2010 at 4:51 PM, Sean Corfield <seanco...@gmail.com> wrote:
I meant to add this link when I posted that info about future git structures:

http://nvie.com/git-model

This one is quite popular, and for good reason it seems! Bob Silverberg has put a good deal of thought into this type of model, for ValidateThis, so it sounds like FW/1 will be moving in a very similar direction. I'll be sure to read up and experiment some more soon. Thanks.
Reply all
Reply to author
Forward
0 new messages