Mailing List Archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tlug] git-fu



Shawn Brown writes:

 > >From a private repo on Github, I want to make a release branch (ok can do).
 > 
 > In a new public repo, I want to clone the release branch.
 > 
 > I need to get the changes in the release branch into the public
 > repo.

In theory, you can directly push/pull from the private repo to the
public one.  I don't know about github's software, maybe this is not
supported.  (Normally you'd need shell access to the host with any
repo you way to pull to/push from.)  Note that push and pull are
somewhat different from each other.  I explain that below.

If not:

 > So do I pull from the release branch into a local repo and then
 > push out to the public repo.

Yes.

 > AFAIK, development will only be in the release branch and non it the
 > public repo.

I'm pretty sure I know what you mean, but in git phrases like "develop
in a branch," taken literally, don't really make sense.  See below.

 > I've never done anything like this.  Does pushing/pull to the release
 > branch from the same local repo where I push to the public repo make
 > sense.

The basic answer is "yes".  If other people are doing (some of) the
work and you're the release manager, then

    release/private repo
             A |
             | V
            local --------> public

(where arrows denote pushes or pulls relative to local) makes sense.
Note that normally you would also push any tags or release info (eg,
NEWS, AUTHORS updates) created for the release from local -> release,
as indicated by the upward arrow.  Local is used for communicating
between private and public, so it probably contains copies of all
branches in both repositories.

If you're doing all the work, then it's not obvious to me why you have
a private branch on github, but whatever the reason, it seems more
logical to push to both repositories from local

    local -> private    (development trunk aka branch "master")
    local -> public     (distribution branch, eg "version-1")

because local is where all changes to the project content are actually
made.  You would probably want to set up the "private" remote to push
all branches, while the "public" remote would only accept pushes from
the released branches.  (Note that "setting up a remote" refers to
configuring the *local* branches.  This actually makes sense because
in git *all* work that the user does is done in the local workspace.
git has to do some work in the remote repositories, but git has few,
if any, commands that work *only* on a remote repository.  Even
commands like "git push --dry-run" require a local repository to
compare to the remote repository.)

Note that the content of versions of files, directories, and commits
with the same SHA1 "names" are guaranteed to be the same no matter
where they are created or stored.  That's why git (and other DVCSes
like hg and bzr) can be distributed: it's just matter of moving around
the content, but the True Names never change ("right, Ged"?)
Repositories on different hosts or even in different workspaces will
overlap (if they contain the same project), but each repository only
contains the objects it needs.  It is (conceptually) easy to
synchronize the needed parts.

In git, branch references ("names" that can be understood by humans),
on the other hand, are *not* shared across repositories or workspaces,
and cannot be.  The reason is that when I work on a project "here",
and you work on the same line of development "there", we think of it
as the *same branch* and we want to refer to it by the *same* name.
But your changes are typically different from mine.  I still think of
my commits as being "on *the* branch," and so do you.  We're both
right, in some sense, but of course our local copies have diverged.

This is one place where the various DVCSes differ substantially.  In
Mercurial (hg) and Bazaar (bzr), for practical purposes workspace ==
branch, and the URL of the workspace is normally used to name it.
Relative URLs (directory names), then, are just abbreviations for
unique names, like calling me "Steve" instead of "Stephen John
Turnbull" (except that URLs are more unique than personal names, as
anybody interested in Japanese military history probably knows --
although I don't actually know that "Stephen Turnbull"'s middle name,
or even if he has one).  The reason for mentioning this is that in
these VCSes, the idea of "working *in* a branch" makes a lot of sense,
because branches are physically located somewhere.

In git, things are more abstract (as you might expect; git usually is
more abstract than other systems).  Git creates namespaces (the most
common one is "origin/") which *can* be linked to other repositories
via URLs and maintained transparently by git-fetch (in which case
they're called "tracking branches"), but can be used for other
purposes by Sufficiently Sophisticated Users (like Sufficiently Smart
Compilers, SSUs may be a pure myth, of course ;-).

What this means is that with git, you "work *on* a branch *in* a
workspace."  And git-pull and git-push are not simply direction-
reversed ways of doing the same thing.  (Ditto, hg.  But in bzr, they
are completely symmetric.)  The basic of ensuring the right objects
are present in both source and target repos is symmetric, of course.
But pull is assumed to be into an *active private workspace*.  git
expects that you will now edit the content.  And it makes a further
assumption, that you want to merge any existing local changes with the
incoming remote changes.  Thus in general git-pull will result in a
local version of the branch that differs from the remote version.
(This is OK, because (1) you know what you're doing because you just
did it :-) and (2) you won't confuse other workers because of the
assumption of a *private* workspace.)

git-push, on the other hand, assumes that the remote is *public*.
Thus it refuses to to do things that would confuse other workers
(rebase a branch), or possibly result in a mess (merge branches).
This restricts git-push to what is called a *fast-forward [merge]*.

If you set up the tracking branches correctly, then git-fetch (and the
higher-level commands like git-push and git-pull) can do all the work
for you.  git-clone will automatically set up an "origin/" namespace
and a local tracking branch for each branch in the origin repository.
I personally usually set up other remotes more or less manually, but
there is a git-remote command to help manage them.



Home | Main Index | Thread Index

Home Page Mailing List Linux and Japan TLUG Members Links