Wink Saville’s Blog

July 5, 2009

git – Remote branches

Filed under: scm — wink @ 1:56 pm

Learned that you can manually create remote branches. This is done having the destination refspec be refs/head. Example:git push ../git2 b2:refs/heads/b2The above will push branch b2 to  repo ../git2.I finally got the force flag (-f) do work. I’ve wanted to do a force when I did a rebase –interactive and of a branch and then wanted to backup it up but I’d get an error about it being a non-fast forward merge. By using <src>:<dst> refspec and the -f it seems to work:

git push ../git2 -f b3:b3

Of course I just tried it and it failed:

error: denying non-fast forward refs/heads/me (you should pull first)To ../git2! [remote rejected] me -> me (non-fast forward)

Also, the following makes and interesting pushes:

git push ../git2 *:*git push ../git2 *:refs/heads/git1-backups/*

I need to investigate how useful they might be?

March 16, 2008

scm – git svn connect

Filed under: linux,scm — wink @ 9:45 pm

The following allows you to reconnect a local clone of a remote svn repo assuming a git repo exists. In my case I have a backup of the remote svn repo but its a pure git repo without any git-svn meta data. Steven Walter provided the basic instructions here.

lcl ~/ $ git clone git://srv/amc.git amc
lcl ~/ $ cd amc
lcl ~/amc $ git svn init -s http://async-msgcomp.googlecode.com/svn
lcl ~/amc $ rm -rf .git/svn
lcl ~/amc $ cp .git/refs/remotes/origin/master .git/refs/remotes/trunk
lcl ~/amc $ git svn fetch

At this point a git svn rebase should indicated “Current branch mastger is up to date.”

March 14, 2008

git – workflow with remote svn repositories

Filed under: programming,scm — wink @ 11:11 am

I’m going to try a new git-svn workflow. Previously I did a git svn clone and also created a backup on my backup server as a remote. So pictorially something like this:

    local-git-svn-clone
           /       \
          /         \
         /           \
remote-svn            backup-server

This worked OK but I’ve made mistakes in the local-git-svn-clone and have had to start all over because things got out of sync. Most often this would happen if I merged into the master branch pushed to the backup-server than then did a “git svn rebase”. I would end up not being able to do any more pushes to the backup-server.

To try to reduce the possibility of mistakes I’m going to try separate repos. So I first. cloned the svn repo as normal:

<local>$ git svn clone -s svn+ssh://wink@<remote-svn-rep>/<path to repo> <local-git-svn-clone>

Then I made a local clone of local-git-svn-clone:

<local>$ git clone local-git-svn-clone local-clone

Next ssh into my backup-server and create a bare shared repo.

<local>$ ssh wink@<backup-server>
<backup-server>$ cd <git-repos>
<backup-server>$ mkdir <backup-repo>
<backup-server>$ cd <backup-repo>
<backup-server>$ git --bare init --shared
<backup-server>$ exit
<local>$

Now back on my local machine I push the local-git-svn-clone repo to the backup repository.

<local>$ cd <local-clone>
<local>$ git remote add backup git://<backup-server>/<backup-repo>
<local>$ git push --repo=backup --all

So at this point <local-clone> points at <local-git-svn-clone> and <backup-repo> which I don’t want. What I want is <local-clone> to just point at <backup-repo>. There may be a simpler way to do this, but I choose to actually delete <local-clone> and create it anew from <backup-repo>.

<local>$ cd ..
<local>$ rm <local-clone>
<local>$ git clone git://<backup-server>/<backup-repo> <local-clone>

So now I have two separate repos on local. <local-clone> connected to <backup-server>/<backup-repo> and <local-git-svn-clone> connected to the <remote-svn-repo>/<path to repo>.

    local-clone    << git pull >>    local-git-svn-clone
           /                                      \
          /                                        \
         /                                          \
back-repo                                          backup-server

Without the direct connection between , but since they are both based on the svn repo I can easily pull local-clone from local-git-svn-clone.

With this configuration you work on branches in local-clone, don’t work on master, the goal is to keep local-clone master exactly the same as local-git-svn-clone. If you don’t do this it will you’ll see trapezoidal commits and things get confusing.

So the work flow becomes:

local-clone$ git checkout -b x
local-clone$ hack
local-clone$ git commit (or git gui)
local-clone$ test
local-clone$ repeat more hack/commit/test
local-clone$ git push --all

So you’ve been working a while and periodically pushing to your back-repo to backup local-clone. Eventually you’ll want to commit the work you’ve done. To do this you’ll pull the changes from local-clone x branch to local-git-svn-clone, svn rebase, test and svn dcommit.

local-git-svn-clone$ git pull <local-clone> x:master
local-git-svn-clone$ git svn rebase
local-git-svn-clone$ test
local-git-svn-clone$ git svn dcommit

If the git svn rebase pulled in a lot of changes you may want to pull these over to local-clone if there and hack/test/commit then back to the above. Eventually you’ll do the svn dcommit.

The last step is to get the changes in local-git-svn-clone into local-clone and push them to backup-repo.

local-clone$ git pull <local-git-svn-clone>
local-clone$ git branch -D x
local-clone$ git push

Of course you don’t need to delete the branch x but all of those changes are now in the local-clone master so they aren’t needed.

February 17, 2008

git – applying patches

Filed under: linux,scm — wink @ 3:49 pm

Today learned some things about git and applying patches. First when applying my trec/ace/kshmem patches to 2.6.25-rc2 they wouldn’t apply because now there only an x86 architecture (arch/x86) instead of two architectures i386 and x86_64. That was to be expected actually and there’s going to be some hand work in doing that.

To do this hand work I really need to see what my current patches look like and there isn’t quite enough context in the patch file to do that, at least for me. So I cloned the current linux-2.6 tree into a new directory linux-2.6-x and did a checkout of 2.6.21-rc6 which is what my patches should apply against.

Well almost, there was still some need for a little tweaking; First git am will take my series of patches which were generated using git format-patch and apply them extracting from the email the commit message and the patch. It then creates a commit. But if there is a problem in a series only those that applied cleanly will be committed.

The first patch that fails won’t be applied at all, for example:

error: patch failed: mm/vmalloc.c:469
error: mm/vmalloc.c: patch does not apply
Patch failed at 0002.
When you have resolved this problem run "git-am --resolved".
If you would prefer to skip this patch, instead run "git-am --skip".

At this point I was scratching my head Patch failed at 0002 and when its resolved I can say so, but how to resolve it if its not been applied to the working tree. The solution is to use “git apply”:

git apply --reject --whitespace=fix my-patches/ace2-2.6.21-rc6/0002.patch

By using “git apply” with the –reject it will apply the patch leaving bad files with “xxx.rej” in my case mm/Kconfig.rej was the culprit. I resolved the problem with mm/Kconfig. Next I tried “git am –resolved”:

wink@ic2d1:$ git am --resolved
Applying ACE implementation, conifguration and makefile
No changes - did you forget to use 'git add'?
When you have resolved this problem run "git-am --resolved".
If you would prefer to skip this patch, instead run "git-am --skip"

More head scratching, “did you forget to use ‘git add’?” …. hm Ok so I then used “git gui” to add the files (BUT DID NOT DO A COMMIT) and then did “git am –resolved”:

wink@ic2d1:$ git am --resolved
Applying ACE implementation, conifguration and makefile
Applying ACE modifications to actually use ACE
.dotest/patch:32: trailing whitespace.
warning: 1 line adds whitespace errors.
Applying ACE simple test program
.dotest/patch:130: space before tab in indent.
result ? "true" : "false", i);
.dotest/patch:138: space before tab in indent.
result ? "true" : "false", i);
.dotest/patch:146: space before tab in indent.
result ? "true" : "false", i);
.dotest/patch:233: trailing whitespace.
warning: 4 lines add whitespace errors.

That did it, so no commit was necessary, the “git am –resolved” did the commit and then continued with the other patches. Lean something new everyday!

January 28, 2008

git – getting git-svn to work

Filed under: scm — wink @ 3:34 pm

I’ve been working with the async-msgcomp svn repository by creating a single working directory with both .git and .svn directories. I then setup each to ignore the others files as well as some files Eclipse uses that should be in the scm. My .git/info/exclude file contains:

 bin
.metadata
R.java
.svn

My [miscellany] section of ~/.subversion/config [miscellany] contains:

 global-ignores = .git bin R.java *.class .metadata *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store

This was fine but did make things laborious as I had to checkin twice, one for each and maintaining the commit comments was painful. At first I figured I do several git checkins then a svn checkin, but it turns out 1:1 seems to work fairly well.

But there is a better way, git-svn, I did find a quick cheat sheet here with the following a suggested work-flow:

git svn clone -s <svn_repo>
git checkout -b <work_branch>

...hack...hack...

git commit -a
git checkout master
git svn rebase
git merge <work_branch>  #NOTE: no need for --squash anymore
git svn dcommit -e  # -e will let you enter a commit message for SVN

When I first tried the first statement (git svn clone <svn_repo> failed with:

 Can't locate SVN/Core.pm in @INC

Searching the Net it turns out I needed to install libsvn-perl via apt/synaptic, after doing so I could clone the async-msgcomp repo using:

git svn clone -s  https://async-msgcomp.googlecode.com/svn --username wink@saville.com async-msgcomp

This looks like a pretty good introduction to git-svn, the only problem is that its for pre 1.5.3.4 and includes the need for a –squash on the merge.

After cloning the svn repo, I also want a backup git repo on my server. Turns out that just following my instructions for setting a remote git repo worked perfectly (actually, doing this led me to find how to use the “git add remote”.

I have run into one problem, if the my git server repo gets out of sync with the svn repo I’m in trouble. The symptom of the trouble is an attempt to push the local repo to the server gets refused because its not a fast forward. This happens if I push to the server before doing the git svn dcommit. The git svn dcommit command places another commit on the local and hence if I’ve all ready pushed before the dcommit it won’t push.

The quickest solution is to remove the current remote, recreate an empty repo on the server as before and push it out again. Alternatively is start all over with a new git svn clone.

December 21, 2007

git – Setting up a remote repo for of a local repo

Filed under: scm — wink @ 6:01 pm

After creating a new local repository either brand new or cloning an existing repo typically I want to push it to my server for backup purposes. To do so I create a bare repository on the server:

mkdir <path-to-repo>/<name-of-repo.git>
cd <path-to-repo>/<name-of-repo.git>
git  --bare init --shared

The repo is now created go back to the local repo and have the local master branch track the remote origin and push it to the remote which we’ve named ‘origin’:

cd <path-to-local-repo>
git remote add -t master origin git://<server>/<name-of-remote.git>
git push origin master

December 13, 2007

scm – Build ID’s

Filed under: linux,programming,scm — wink @ 10:21 pm

A BuildID is being added to the gnu linker, ld, by Roland McGrath. I saw this mentioned in these instructions for building the Android kernel from source, which didn’t support the new switch and it had to be disabled.

Anyway, Roland had a problem where he wanted to identify exactly where the binaries came from when inspecting a post-mortem dump. Especially when the dump could have happened long after the build was actually done. While at nxp we had this problem and generally relied upon the svn release number. That worked but isn’t actually unique enough especially when a particular build might be one by a developer and not an official release.

Anyway, this looks to be a possible solution

December 10, 2007

Git submodule and “how-to combine muliple git-repos”

Filed under: programming,scm — wink @ 2:47 am

Ok, I leaned what git submodule is for, well at least I think so. Apparently its primary use to as a mechanism for tagging a set of repositories, see my post here, which starts here. What help the most was looking at the tutorial here.

The as it indicates in the Title my original goal was to have some way of combining multiple git-repos. git-submodule doesn’t really do that and there doesn’t seem any easy way to do it. But Daniel Barkalow provided me with the instructions below which did combine them with linear history which is just fine. I do not understand why it works and I also wonder how the instructions might be changed if there were multiple branches in one of the repository and I had wanted to get that history also? Anyway, questions for the future.

Ah, okay. I was assuming that you wanted them to maintain their original identities (so you'd send stuff off for each of them separately, for example). I think you can do what you want by doing: # Set up the new line: $ mkdir x; cd x $ git init $ touch README $ git add README $ git commit # Add a project "foo" $ git fetch ../foo refs/heads/master:refs/heads/foo $ git merge --no-commit foo $ git read-tree --reset -u HEAD $ git read-tree -u --prefix=foo/ foo $ git commit And repeat for all of the other projects. What's going on here is that you're merging in each project, except that you're moving all of the files from that project into a subdirectory as you pull in the content. The resulting repository has one recent dull initial commit, and then merges in each of the other projects with their history, with only the slight oddity that they don't go back to the same initial commit, and the merge renames all of the project's files. I think there may be a more obvious way of doing this (it's essentially how gitweb and git-gui got into the git history), but I'm not sure what it is, if there is one. -Daniel

After this post, Daniel came back with a nice explanation for what each line did, you can see the post here.

October 28, 2007

git branching

Filed under: scm — wink @ 12:57 am

Here is a nice introduction to git. In particular the instructions for adding a branch worked quite well. For sparkrocket I wanted to create a new branch for testing. In the git-repos there was no branch so the question arises how to add a new branch and push it to the current repository.

Creating a local branch is easy:

git checkout -b test

I had made modifications so I checked them in after branching:

git commit -a

I then did a push all as indicated from the tutorial but if I remember correctly I didn’t indicate the repo I just did the “–all”

git push –all

Either way test was pushed to the sparkrocket repo on .0.8. But I also had a clone of the repo on my my other machine 0.133 and when I did a git pull the test branch was added and we can see it in the remotes:

wink@ic2d1:~/prgs/sparkrocket$ find . -iname ‘test’
./.git/logs/refs/remotes/origin/test
./.git/refs/remotes/origin/test

but not in heads as it is on .0.8:

root@saville-server:/var/www/sparkrocket# find . -name ‘test’
./.git/refs/heads/test
./.git/refs/remotes/origin/test
./.git/logs/refs/heads/test
./.git/logs/refs/remotes/origin/test

but it wasn’t in .git/refs/heads/test. After a few false starts it looks like the way to get it to be “visible” on 0.133 was to check it out and then add it as a branch.

git checkout c37c761d48bcf6cbb0d1cb987e074f86a587182a
git checkout -b test

This looks to have done the correct things, doing a find for test we see the same as on .0.8:

wink@ic2d1:~/prgs/sparkrocket$ find . -iname ‘test’
./.git/logs/refs/remotes/origin/test
./.git/logs/refs/heads/test
./.git/refs/remotes/origin/test
./.git/refs/heads/test

—Update

Didn’t quite work, after an additional modification on .0.8 I pushed the change to the repo and then pull it back down to .0.133. All was well but for the final step:

wink@ic2d1:~/prgs/sparkrocket$ git pull
remote: Generating pack…
remote: Done counting 7 objects.
Result has 4 objects.
remote: Deltifying 4 objects…
remote: 100% (4/4) done
remote: Total 4 (delta 3), reused 0 (delta 0)
Unpacking 4 objects…
100% (4/4) done
* refs/remotes/origin/test: fast forward to branch ‘test’ of git://192.168.0.8/sparkrocket
old..new: c37c761..d103e89
Warning: No merge candidate found because value of config option
“branch.test.merge” does not match any remote branch fetched.
No changes.

— Update 2007-10-28

Figured it out, turns out that even on 0.8 a “git pull” didn’t work and emitted the exact same message that there was no merge candidate. So I looked at .git/config and decided to add another branch section for test, that worked so the config file on 0.8 and 0.133 is:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = git://192.168.0.8/sparkrocket.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
[branch "test"]
        remote = origin
        merge = refs/heads/test

So adding the [branch "test"] did the trick.

Powered by WordPress