[coreboot] Git

Peter Stuge peter at stuge.se
Fri Mar 8 13:15:30 CET 2013


Hi Wolfgang,

Wolfgang Kamp - datakamp wrote:
> I'm struggling with git to send a commit. The Git show command
> shows what I really want to commit.

That's good, it means that you have created a commit locally with
what the desired changes.

Before pushing the only thing to check is that there are no other
commits on the same branch.


> The Git log origin/master command shows a lot of commit messages
> for every patch ever done.

That's correct. git log shows the history going *back* in time
starting from the point that you specify. When you specify
origin/master you get all commits leading up to your current
origin/master, which is a so-called remote tracking branch, within
your repository. This branch should be left read-only, except when
running git fetch or git pull to make it up-to-date with what is in
the public repository.

Please run instead:

git log origin/master..HEAD

Or shorter:

git log origin/master..

You can leave out HEAD if you like, but you must include the two dots.

Instead of specifying a single point like before, these commands
specify a range of commits. When you specify this range you'll be
shown only the commits in HEAD which are based on origin/master.

HEAD means "the last commit on the current branch"


> I think the git push origin command will send all the commit
> history and not only my commit.

No, git only sends new commits. So if the above log origin/master..
command only shows the same commit as git show, then that is the only
thing that will be sent.


A brief explanation of the git data model, maybe it's already known:

Files are called blobs, directories are called trees. Trees contain
blobs and other trees. There is a top-level tree corresponding to the
root directory of the repo. Blobs and trees are identified solely by
their hash, which is calculated from their contents.

A commit consists of only:

The top-level tree hash
Zero or more parent commit hashes
Author name, email and timestamp
Committer name, email and timestamp
The commit message
[optional PGP signature]

Commits are also identified by a hash calculated from their contents.

If any of the data in the commit (a blob, which bubbles up to the
root tree, or the commit timestamp, or the commit message) changes,
then the commit id also changes. Commits can be said to be immutable,
it's not really possible to change a commit. It is however possible
to *replace* it.

Commits are organized into branches. A branch is just a nickname for
some particular commit, but with special semantics: Whenever a new
commit is created, the current branch is changed to refer to the new
commit.

A tag is also a nickname for a commit, but tags must and do never change.

If a commit has zero parents it is generally the very first commit in
the repository. It's theoretically possible to have multiple commits
like that on different branches, but that's a rare occurance.

If a commit has more than one parent it is called a merge commit,
because it joins together multiple branches.

Most commits have just one parent.

Try the command: git show --pretty=raw

Or maybe even better: git log --pretty=raw

..in your own repo. Compare parent lines with the following commit
lines. You should see how the commits chain together, forming a DAG,
direct acyclic graph, similar to a linked list going back in time.

Note that the diff, ie. the changes in all files, isn't stored
anywhere by git. The diff is generated each time by comparing
which blobs changed between two root trees.


Creating a branch is cheap, fast, fun and easy.

git branch $name $startingpoint

$startingpoint is anything that identifies a commit; a branch name, a
tag name, or a commit hash. The new branch is strictly local, like
almost everything that you do with git.

The command: git branch -a -v

Shows -a(ll) branches in your repository -v(erbosely), meaning that
you will see both your local branches and your "remote" or "remote
tracking" branches. The remote branches are the for-reading-only ones
like origin/master. You literally have a local copy of every commit
in every branch that existed on the remote when you cloned or
fetched/pulled last time. Verbose means that you are shown the
abbreviated commit hash and the commit message summary for the commit
that is HEAD of each branch.

git fetch downloads new commits into your remote tracking branches
but makes no changes to your local branches.

git pull is by default: git fetch && git merge

pull thus performs a merge of your current branch with the updated
remote branch that it is based on.

If you have created a new commit locally, and at the same time there
are also new commits from the server, then your current branch and
the remote branch are said to have diverged.

git merge will in that case create a merge commit with two parents,
namely your last commit and the last commit on the remote.

We generally avoid merge commits in coreboot, so it's good to run:

git pull --rebase

instead of simply git pull. This amounts to: git fetch && git rebase

So rebase, instead of merge.

Rebasing is a lot of fun, it takes your local commits which you
created based on the old origin/master and instead of merging it
simply tries to re-apply (re-base) them on top of the latest state of
origin/master. If something changed on the remote where you have made
changes, you get a conflict which you will have to resolve somehow.
(Merging can have conflicts too of course.)


I hope that helps some.. Feel free to ask if you have other
questions. I can recommend #git on irc.freenode.org as well as the
book Pro Git available at http://git-scm.com/book and the lighter
weight Git reference site at http://gitref.org/


//Peter



More information about the coreboot mailing list