Patrick (patrickwonders) wrote,
Patrick
patrickwonders

  • Mood:

VCS Whoas

I've got tons of my world under version control. I've got version control on LaTeX macros, SQL dumps, source code, my resume, my website, other peoples' websites, my .profile, yada, yada, yada. The older stuff is in CVS (some migrated from RCS). More recent stuff is in monotone. Still more recent stuff is in subversion so that I didn't have to keep rebuilding Boost on my ancient Linux distro every time I upgraded monotone.

But, I've hit a roadblock. CVS didn't have any way to reference an external repository (though, I've been known to pretend like it did with unmaintainable symlinks in the repository directories). Monotone didn't handle them very well. And, subversion has some really big caveats with them. Without external repositories, code re-use is questionable at best. I want to re-use the PHP utilities I made for that website on this website.... well, copy them on over or put an ignored symlink in this working copy over to that working copy or keep everything in one repository where you manually maintain foo/bar/utils/ as a branched copy of qux/quux/utils/. Yuck.

After reading this article about git, I thought I should give it a shot. So, I was following along with the submodules section of the git manual.

sirrobin:~> mkdir ~/tmp/git
sirrobin:~> cd ~/tmp/git
sirrobin:~/tmp/git> for sub in foo bar baz; do
> mkdir $sub
> cd $sub
> git init
> echo "$sub project" > $sub.txt
> git add $sub.txt
> git commit -m 'Initial version'
> cd ..
> done
Initialized empty Git repository in .git/
Created initial commit 1d10c85: Initial version
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 foo.txt
Initialized empty Git repository in .git/
Created initial commit 71dfb10: Initial version
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 bar.txt
Initialized empty Git repository in .git/
Created initial commit 041b64b: Initial version
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 baz.txt
sirrobin:~/tmp/git> ls -F
bar/	baz/	foo/

So far, so good. I have three projects that I'm going to include in my super project. Now, I'll make my super project.

sirrobin:~/tmp/git> mkdir super
sirrobin:~/tmp/git> cd super
sirrobin:~/tmp/git/super> git init
Initialized empty Git repository in .git/
sirrobin:~/tmp/git/super> echo 'Master project' > README.txt
sirrobin:~/tmp/git/super> git add README.txt
sirrobin:~/tmp/git/super> for sub in foo bar baz; do
> git submodule add ~/tmp/git/$sub
> done
Initialized empty Git repository in /Users/pat/tmp/git/super/foo/.git/
Initialized empty Git repository in /Users/pat/tmp/git/super/bar/.git/
Initialized empty Git repository in /Users/pat/tmp/git/super/baz/.git/
sirrobin:~/tmp/git/super> ls
README.txt	bar		baz		foo
sirrobin:~/tmp/git/super> git commit -m 'Initial version of master project'
Created initial commit 58a4163: Initial version of master project
 5 files changed, 13 insertions(+), 0 deletions(-)
 create mode 100644 .gitmodules
 create mode 100644 README.txt
 create mode 160000 bar
 create mode 160000 baz
 create mode 160000 foo
sirrobin:~/tmp/git/super> cd ..
sirrobin:~/tmp/git> ls -F
bar/	baz/	foo/	super/

Now, I'll clone it, make some changes to the foo subproject, and commit all of my changes.

sirrobin:~/tmp/git> git clone super cloned
Initialized empty Git repository in /Users/pat/tmp/git/cloned/.git/
sirrobin:~/tmp/git> cd cloned
sirrobin:~/tmp/git/cloned> ls -F
README.txt	bar/		baz/		foo/
sirrobin:~/tmp/git/cloned> git submodule init
Submodule 'bar' (/Users/pat/tmp/git/bar/.git) registered for path 'bar'
Submodule 'baz' (/Users/pat/tmp/git/baz/.git) registered for path 'baz'
Submodule 'foo' (/Users/pat/tmp/git/foo/.git) registered for path 'foo'
sirrobin:~/tmp/git/cloned> git submodule update
Initialized empty Git repository in /Users/pat/tmp/git/cloned/bar/.git/
Submodule path 'bar': checked out '71dfb100f5816b6e0bf71b5795835f016a660386'
Initialized empty Git repository in /Users/pat/tmp/git/cloned/baz/.git/
Submodule path 'baz': checked out '041b64b70dce8769661dddb8061885d8d6d3f144'
Initialized empty Git repository in /Users/pat/tmp/git/cloned/foo/.git/
Submodule path 'foo': checked out '1d10c859abf1764c207e31350b98183e1945fdd5'
sirrobin:~/tmp/git/cloned> cd foo
sirrobin:~/tmp/git/cloned/foo> ls -F
foo.txt
sirrobin:~/tmp/git/cloned/foo> git branch
* (no branch)
  master
sirrobin:~/tmp/git/cloned/foo> git checkout master
Switched to branch "master"
sirrobin:~/tmp/git/cloned/foo> git mv foo.txt README.txt
sirrobin:~/tmp/git/cloned/foo> ls -F
README.txt
sirrobin:~/tmp/git/cloned/foo> git commit -a -m 'Moving foo.txt to README.txt'
Created commit 774d416: Moving foo.txt to README.txt
 2 files changed, 1 insertions(+), 1 deletions(-)
 create mode 100644 README.txt
 delete mode 100644 foo.txt
sirrobin:~/tmp/git/cloned/foo> git push
updating 'refs/heads/master'
  from 1d10c859abf1764c207e31350b98183e1945fdd5
  to   774d4166bbe2b2f077de62d7ccdf5391a951a5ff
 Also local refs/remotes/origin/master
Generating pack...
Done counting 3 objects.
Result has 2 objects.
Deltifying 2 objects...
   0% (0/2) done  50% (1/2) done 100% (2/2) done
Writing 2 objects...
  50% (1/2) done 100% (2/2) done
Total 2 (delta 0), reused 0 (delta 0)
Unpacking 2 objects...
  50% (1/2) done 100% (2/2) done
refs/heads/master: 1d10c859abf1764c207e31350b98183e1945fdd5 -> 774d4166bbe2b2f077de62d7ccdf5391a951a5ff
sirrobin:~/tmp/git/cloned/foo> cd ..
sirrobin:~/tmp/git/cloned> git status
# On branch master
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#
#	modified:   foo
#
no changes added to commit (use "git add" and/or "git commit -a")
sirrobin:~/tmp/git/cloned> git commit -a "Moved foo's README around"
Created commit 123776a: Moved foo's README around
 1 files changed, 1 insertions(+), 1 deletions(-)
sirrobin:~/tmp/git/cloned> git push
updating 'refs/heads/master'
  from 58a4163c3647a79f5fe3be9c685f28ddefbfd3ea
  to   123776a66bafbe38f342bba40250f6199a207f8a
 Also local refs/remotes/origin/master
Generating pack...
Done counting 3 objects.
Result has 2 objects.
Deltifying 2 objects...
   0% (0/2) done  50% (1/2) done 100% (2/2) done
Writing 2 objects...
  50% (1/2) done 100% (2/2) done
Total 2 (delta 1), reused 0 (delta 0)
Unpacking 2 objects...
  50% (1/2) done 100% (2/2) done
refs/heads/master: 58a4163c3647a79f5fe3be9c685f28ddefbfd3ea -> 123776a66bafbe38f342bba40250f6199a207f8a

So far, so good. I'm gonna go back into the super project master and see how things look from there.

sirrobin:~/tmp/git/cloned> cd ../super/foo
sirrobin:~/tmp/git/super/foo> ls -F
foo.txt
sirrobin:~/tmp/git/super/foo> git log .
commit 1d10c859abf1764c207e31350b98183e1945fdd5
Author: Patrick Stein <pat@nklein.com>
Date:   Fri Apr 18 12:14:53 2008 -0500

    Initial version
sirrobin:~/tmp/git/super/foo> git pull
remote: Generating pack...
remote: Done counting 3 objects.
remote: Result has 2 objects.
remote: Deltifying 2 objects...
remote:    0% (0/2) doneremote:   50% (1/2) doneremote:  100% (2/2) doneremote: 
Unpacking 2 objects...
remote: Total 2 (delta 0), reused 0 (delta 0)
  50% (1/2) done 100% (2/2) done
* refs/remotes/origin/master: fast forward to branch 'master' of /Users/pat/tmp/git/foo/
  old..new: 1d10c85..774d416
Updating 1d10c85..774d416
Fast forward
 foo.txt => README.txt |    0 
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename foo.txt => README.txt (100%)
sirrobin:~/tmp/git/super/foo> ls -F
README.txt

Okay, so I'm cooking with Crisco now. I've made a bunch of little projects. I've made a super project to in the darkness bind them. I cloned that super project. I made changes to the sub in that clone. I pushed them back to the super. But, now I'm stuck.

The directory ~/tmp/git/foo is both a working copy and a repository for the project foo. I've updated the repository for it, but I cannot figure out how to update the working copy that's there. In fact, even worse, the working copy that's there thinks (and rightly so) that it represents a change which will undo everything that I've done. I don't want that. I want to incorporate the changes that have been committed from the cloned super. And, I cannot figure out how to do it.

sirrobin:~/tmp/git/super/foo> cd ../../foo
sirrobin:~/tmp/git/foo> ls -F
foo.txt
sirrobin:~/tmp/git/foo> git log .
commit 774d4166bbe2b2f077de62d7ccdf5391a951a5ff
Author: Patrick Stein <pat@nklein.com>
Date:   Fri Apr 18 12:20:26 2008 -0500

    Moving foo.txt to README.txt

commit 1d10c859abf1764c207e31350b98183e1945fdd5
Author: Patrick Stein <pat@nklein.com>
Date:   Fri Apr 18 12:14:53 2008 -0500

    Initial version
sirrobin:~/tmp/git/foo> git pull
fatal: 'origin': unable to chdir or not a git archive
fatal: The remote end hung up unexpectedly
Cannot get the repository state from origin
sirrobin:~/tmp/git/foo> git pull .
Already up-to-date.
sirrobin:~/tmp/git/foo> git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#	renamed:    README.txt -> foo.txt
#
sirrobin:~/tmp/git/foo> git merge HEAD
Already up-to-date.

Further, git revert wants to revert the last commit, not revert my current "changes". And, git checkout HEAD gives me README.txt but now thinks I still want to add foo.txt. Its recommendation here of using git reset HEAD seems like a good idea, but it no-ops with a message I don't know how to respond to:

sirrobin:~/tmp/git/foo> git reset HEAD
README.txt: needs update

I feel like I'm missing something fundamental.

Tags: ask lj, git, vcs
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 3 comments