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
Peter Stuge wrote:
HEAD means "the last commit on the current branch"
"the last commit on the branch" is better, since HEAD is used to refer to other branches as well.
A tag is also a nickname for a commit, but tags must and do never change.
I lied. I should have written:
tags SHOULD never change.
It is possible to delete a tag, and create a new tag with the same name as the old one, but referencing a different commit. This should always be avoided however. If people can't trust tags to stay still then why use tags in the first place.
We generally avoid merge commits in coreboot
Merge commits are append-only and exactly preserve development history. Alert readers noticed that a rebase means that commits must change. This is frowned upon if someone has already seen the commits as they were before the rebase, but it is perfectly fine if they only exist locally.
The killer feature in git is "interactive rebase", which allows to rework any number of commits in any desirable way. It's very clever, and makes it very easy to clean up after some problems or mistakes.
//Peter
Peter Stuge wrote:
We generally avoid merge commits in coreboot
Merge commits are append-only and exactly preserve development history. Alert readers noticed that a rebase means that commits must change. This is frowned upon if someone has already seen the commits as they were before the rebase, but it is perfectly fine if they only exist locally.
Using Gerrit allows us to comfortably rework commits until we are happy with them, without needing to rewrite any branch in coreboot.git. Gerrit acts as a buffer, where anything goes, until the commits are "submitted" into coreboot.git.
//Peter