wiki:explainGIT

This is a simple guide for developers, to allow a common tree structure and commit messages for every package stored into the main repository.

The below is work in progress:

First of all, I want to give you a couple of tricks on how to do house keeping WRT pulling new changes from upstream in our git. According to our workflow, we periodically want to take new changes from the upstream branch we currently base our OS/2 releases on, as well as to switch to a new upstream branch when we think it’s time to do so for the OS/2 version.

Either we take a new branch or update the existing one, the process consists of two steps: a) bring the upstream branch to our github fork and b) merge this branch to the corresponding OS/2 branch in our fork. But before going further with this, some explanation of links between repositories is necessary. When you clone a repository locally, git creates only one link to the external world: to the repository you clone (referred to as origin). In our case, this is our gcc fork at github (https://github.com/psmedley/gcc). All further links (including the one referred to as upstream, which points to the original repository our github repo forked, https://github.com/gcc-mirror/gcc) must be done manually for each local clone. The command for it is rather simple though:

git remote add upstream https://github.com/mirrors/gcc.git

And now are the steps for a) (I took the 4.9 branch as an example):

git fetch --tags upstream gcc-4_9-branch # download upstream changes (with tags) to our local repo 
git checkout gcc-4_9-branch # switch to our local branch corresponding to upstream
git merge upstream/gcc-4_9-branch # merge upstream changes to our local branch
git push --tags -u origin gcc-4_9-branch # upload all updates we made to our github repo (origin)

Note that «our local branch» above doesn’t mean the OS/2 branch. It means a clone of the original upstream branch in our github repo. Since we never modify original upstream branches in our work flow, the merge step will always be a fully automatic fast-forward operation which always applies cleanly and never creates any new commits (or conflicts).

Note that if you are about to take a new branch from upstream (i.e. a branch that it’s absent in origin), these commands will care about creation of the new branch automatically. The merge step may be omitted in this case as there is nothing to merge (it.s safe to do this step though, it will simply say that it’s already up-to-date). However, the -u (--set-upstream) flag of the push step is very important in this case since after the initial checkout the local branch will be bound to the upstream repo and this flag will make it re-bound to origin (where it should be bound).

Note that if you omit the branch specification (i.e. gcc-4_9-branch in the example above), it will take all existing branches from upstream and push them to origin. This may be time consuming and will blow up the origin repo if the upstream repository is huge, so it’s usually better to specify a single branch unless it’s absolutely necessary to perform a complete sync.

Now let’s talk about b) assuming we switch our OS/2 development to a new upstream branch.

git checkout -b gcc-4_9-branch-os2 gcc-4_9_2-release # create a new OS/2 branch starting it at the specific tag
git push -u origin gcc-4_9-branch-os2 # upload the new branch to our github repo (origin)

When these steps are done we need to bring all relevant OS/2 changes to the new branch (which may include all OS/2 changes if the new branch originates from some point in history where no OS/2 patches ever existed). This is a big separate discussion, I will write a separate letter on that topic. Let’s omit that for now and assume you somehow merged the changes which you may push with:

git push

This assumes ‘push.default’ is set to ‘simple’ so that it will only push the current branch to the linked upstream branch (origin/gcc-4_9-branch-os2 in this case).

Here are the commands to update the existing OS/2 branch with the new commits from upstream:

git checkout gcc-4_9-branch-os2 # switch to the OS/2 branch
git merge gcc-4_9_2-release # merge upstream changes corresponding to the given tag
        …                                                     # resolve possible conflicts (discussed elsewhere)
git push # assumes push.default = simple

Note that the tag you use in the merge command must mark a point in history of the original upstream branch (gcc-4_9-branch in this case) after the split — i.e. after the commit where the OS/2 branch was started off or last time merged with it. If you specify an unrelated commit, you may create a weird history that doesn’t make any sense from the perspective of our work flow.

A tiny hint: If the merge somehow fails and you want to start it over, you may abort the current merge with just:

git merge --abort

It should reset the repository to the state it was before issuing the merge command. Note that the abort command will most likely not work correctly if you execute any other git command that modifies the state of files in between.

Last modified 2 years ago Last modified on Jan 21, 2015, 1:51:25 PM