# Re: policy and mechanism for less-connected clients

7 messages from 2008-06-25 to 2016-08-14. Participants: David Jeske, Jakub Narebski, Junio C Hamano.
Thread: https://gitlist.dev/t/14153

## David Jeske, 2008-06-25 21:35

Subject: Re: policy and mechanism for less-connected clients
Message-ID: <1784.50359167091$1214430241@news.gmane.org>
URL: https://gitlist.dev/e/1784.50359167091%241214430241%40news.gmane.org
In-Reply-To: <willow-jeske-01l6XqjOFEDjC=91jv>

```
Some answers thanks to Jakub...

-- David Jeske wrote:
> : "ncvs up" ->
> :
> : git stash; git pull; git apply;
> : git diff --stat <baseof:current branch> - un-pushed filenames
> : git-show-branch <current branch> - un-pushed comments
>
> Question: when I say "baseof:current branch", I mean "the common-ancestor
> between my local-repo tracking branch and the remote-repo branch it's
> tracking". How do I find that out?

I'm told I need...

git diff --stat `git-merge-base HEAD ORIG_HEAD`

> : "ncvs commit" -> "git commit; git push <only this branch>;"
>
> Question: how do I only push the branch I'm on? "eg" says it does this, but
> from a quick look at the code, it wasn't obvious to me how.

and...

git push HEAD


which just leaves this one....

Question: How do I create a branch on a remote repo when I'm on
my local machine, without sshing to it?

```

## Jakub Narebski, 2008-06-25 22:10

Subject: Re: policy and mechanism for less-connected clients
Message-ID: <g3ufoa$ps3$1@ger.gmane.org>
URL: https://gitlist.dev/e/g3ufoa%24ps3%241%40ger.gmane.org
In-Reply-To: <1784.50359167091$1214430241@news.gmane.org>

```
David Jeske wrote:

> Question: How do I create a branch on a remote repo when I'm on
> my local machine, without sshing to it?

Push into it.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

```

## Junio C Hamano, 2008-06-25 22:13

Subject: Re: policy and mechanism for less-connected clients
Message-ID: <7viqvxxix0.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7viqvxxix0.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <1784.50359167091$1214430241@news.gmane.org>

```
"David Jeske" <jeske@willowmail.com> writes:

>> : "ncvs up" ->
>> :
>> : git stash; git pull; git apply;

First of all, if you are in CVS mindset, you may not want to necessarily
do "git pull", but "git fetch" followed by "git rebase".

I suspect the last one in the above sequence of yours is "git stash pop".
Definitely not "git apply" without any argument which is a no-op.

>> : git diff --stat <baseof:current branch> - un-pushed filenames

"git diff [--options] origin..." (three-dots) is often used.  This is a
shorthand for:

	git diff [--options] $(git merge-base origin HEAD) HEAD

that is, "show me what I did since I forked from origin".

>> : git-show-branch <current branch> - un-pushed comments

This would be useful if you are using "fetch + rebase", but in any case

	git log --graph --pretty=oneline origin..

may be prettier these days.  --graph is a recent invention that appeared
first in 1.5.6.

> Question: How do I create a branch on a remote repo when I'm on
> my local machine, without sshing to it?

I hope that the question is not "How do I do anything on a remote without
having any network connection to it" as its answer cannot be anything but
"telepathy".

```

## David Jeske, 2008-06-25 23:02

Subject: Re: policy and mechanism for less-connected clients
Message-ID: <9505.40933195061$1214435222@news.gmane.org>
URL: https://gitlist.dev/e/9505.40933195061%241214435222%40news.gmane.org
In-Reply-To: <7viqvxxix0.fsf@gitster.siamese.dyndns.org>

```
-- Junio C Hamano wrote:
> >> : "ncvs up" ->
> >> :
> >> : git stash; git pull; git apply;
>
> First of all, if you are in CVS mindset, you may not want to necessarily
> do "git pull", but "git fetch" followed by "git rebase".

I don't want to replicate CVS behavior, just the workflow. I've considered
rebase, but the diagrams on the documentation page look scarry. I want to keep
the dag-nodes made by their local git commit;. At those commits the code worked
and tested in their tree. rebase looks like it tosses those dag-nodes when it
rewrites the diffs -- who knows if the tests actually pass for every point
along that new rebase. That's no good.

I can see the use of rebase when your job is to "author an understandable
public source tree", but I'm working on SCM, where the goal is to be able to
reproduce the state of past successes reliably.

I want someone to be able to checkout what was actually in the user's local
client as they were working. Which means I think I want "fetch and merge" which
is pull. Did I get that wrong?

> I suspect the last one in the above sequence of yours is "git stash pop".
> Definitely not "git apply" without any argument which is a no-op.

I meant to type "git stash apply", but I think you're right, pop is what I
wanted.

> >> : git diff --stat <baseof:current branch> - un-pushed filenames
>
> "git diff [--options] origin..." (three-dots) is often used. This is a
> shorthand for:
>
> git diff [--options] $(git merge-base origin HEAD) HEAD
>
> that is, "show me what I did since I forked from origin".

I'm still a little foggy on the remote referenecs, but remember I have two
remotes (shared) and (personal). Something in the docs led me to believe
'origin' was repository wide, not private to each branch. Is "origin" a magic
name for the current branch's target?

> >> : git-show-branch <current branch> - un-pushed comments
>
> This would be useful if you are using "fetch + rebase", but in any case
>
> git log --graph --pretty=oneline origin..

Ahh, yes, Thanks!. How does this interact with the "pull" I just did?

What I want is "show me the commit messages (and sha1 keys) for changes in my
local branch that are not yet submitted to it's remote tracking location"

Will that command above include the commit lines that came down in my pull
(fetch/merge)? If so, how do I not include them?

> > Question: How do I create a branch on a remote repo when I'm on
> > my local machine, without sshing to it?
>
> I hope that the question is not "How do I do anything on a remote without
> having any network connection to it" as its answer cannot be anything but
> "telepathy".

Funny. I'm asking how I can run a command locally, that during the next "git
push HEAD" will cause a branch to be created on a remote repository, without
assuming that is the same repository that my current branch is pointing to.
Will this do the trick?

git branch --track mynewbranch git://myserver/path/foo.git
# hack hack
git commit
git push HEAD

- David

```

## David Jeske, 2016-08-14 00:43

Subject: Re: policy and mechanism for less-connected clients
Message-ID: <willow-jeske-01l6XqjOFEDjC=91jv>
URL: https://gitlist.dev/e/willow-jeske-01l6XqjOFEDjC%3D91jv
In-Reply-To: <20080625133458.GE20361@mit.edu>

```
Thanks for the info about shared object storage for shared repositories. That's
great, and looks like a good implementation method.

Previously I was thinking in terms of making a different server to change
behavior. However, I think the comments I've read are shifting my mindset
towards making a client-wrapper. I want to provide a system [wrapper] without
the user-burden of thinking about three repositories (local, my-public,
shared-public). Doing this as a wrapper has other benefits, like the fact that
users can treat services like repo.or.cz as the "networked filesystem of their
version control system", so I like it.

I have a model for the operations of this wrapper below.

-- Theodore Tso wrote:
> [snip] sharing in-progress work is highly overrated.

_Seeing_ unfinished changes is overrated. However, so is managing multiple
repositories and managing which data is shared.

I think my new wrapper approach below eliminates this overly-aggressive sharing
while still reducing complexity for the average user.

> So the way I would do things is to simply encourage people to do start
> their work by branching off of an up-to-date master branch, but *not*
> do any git pulls or git pushes.

You confused me here. If their repo.or.cz private repository is their only way
of sharing (because their home directory is inaccessible and emailing patches
is cumbersome), how do they exchange their own changes without pushing? Even in
a short time on git mailing list I see mini-unfinished-patches being posted.

> [ description of commit rewriting, rebase, push ]

The method you describe is burdening all users with learning a bunch of new
concepts to do things that are unnecessary micromanagement for their needs. I'd
prefer to give my users many of the benefits of DVCS/git with a
command/argument set 1/20th the size and a much simpler mental model.

Most of the software we're all using was developed while working with
centralized source control, where people just hack and commit and those commits
are not even known-working. They don't bother with patch/commit rewriting and
management, and it works out just fine. I can see how that finer granularity
may be valuable for linux kernel coordinators. However, most projects don't
need to bother with all that, and even in the ones that do, most of their
contributors don't.

Despite the success of centralized revision control, distributed source control
revision models have some very attractive features which can add efficiency to
a shared-central-repo model without straying far from the familiar (cvs up;
hack; hack; cvs up; cvs commit;) workflow. I read some commentary from Linus
that compared git to a 'filesystem', and that's what I see.. a really awesome
underlying set of mechanisms for implementing SCM.. I'm trying to understand
how to layer an easy to use SCM system on top if it.

Some 'git' users might say the right thing to do is do a different project, but
I think, just like with the filesystem-analogy, there is significant benefit to
sharing a single repository model so a simple source control system can then be
used in powerful ways by powerful users. This is similar to the direction "eg"
(easy git) is heading, but more extreme and extending to the server.

In fact, it seems like we might be better off if all of these source control
user-interfaces (cvs, perforce, git, eg, mercurial, etc. etc.) could be written
on top of a version-control-api that they shared. Witness the similar
implementation strategies of this modern rash of DVCS systems.

--------------------------------------------------------------

I'll try to explain my wrapper model in terms of an example... Imagine I'm
going to deliver a "cvs drop in replacement", ncvs, that mostly keeps the cvs
mental model, but is implemented underneath using git and just works better
than cvs (yet is simpler than git). I'll use the exact cvs command parameters
for illustration, but I wouldn't plan to do this. Notice how each ncvs command
uses many git commands. It's possible these things should be done in terms of
plumbing instead of porcelain to reduce dependence on git changes, but it's
more concise to express them as porcelain.

>From the earlier feedback, there are now two repositories, one is considered
the "shared-root" while the other is the "user" repository.

(1) make "cvs update" safe, make it easy to see granular comments for things
you have not pushed

CVS users do potentially destructive merges all the time. Despite the way we
use terminology, working files ARE a branch, and "cvs up" IS a merge. That
merge can require edits to resolve, and after those edits are complete, the
previous state is NOT recoverable. There is no reason for this. We can easily
save the delta by just making "cvs up" equal "git commit; git pull;", or
alternately, "git stash; git pull; git apply;".

: "ncvs up" ->
:
: git stash; git pull; git apply;
: git diff --stat <baseof:current branch> - un-pushed filenames
: git-show-branch <current branch> - un-pushed comments

Question: when I say "baseof:current branch", I mean "the common-ancestor
between my local-repo tracking branch and the remote-repo branch it's
tracking". How do I find that out?

Adding "git diff --stat <baseof:current branch>" helps keep us aware of what
changes are in our local repo. Any files not pushed up to the branch head on
the server are seen. Likewise with "git-show-branch <current branch>" (which
somehow is not the same as git-show-branch --current).

(2) make "planned ahead of time" branches cheap to make

"cvs up" is the easiest merge in cvs, therefore, separate sets of checked out
working files become the most common form of branching in cvs. They are
basically personal work branches that you can't commit on, and can't
collaborate on. I've seen developers with cvs working directories weeks or
months old because that's an easier way to work on different ideas than
creating a branch and checking them in. DVCS fixes this, by making branches
cheap to make, and by making all branch merges closer to the simplicity of
cvs's easy branch merge "cvs up". However, I don't need to burden the user with
the extra complexity and workload of the default being local branches, which
they then need to do more work to share. I want branches to be shared by
default.

: "ncvs tag -b --shared $branch" ->
:
: [ create a branch on the "shared root" repo, pointing
:   to where I am in my local tree, if I have permission ]
:  git branch --track $branch origin/$branch

: "ncvs tag -b mybranch
:
: [ create a branch on my "user" repo, pointing to where I am
in my local tree, if I have permission ]
: git branch --track $mybranch my-origin/$branch

Question: I'm not sure what commands to use above. How do I create a branch on
a remote repo when I'm on my local machine, without sshing to it?

The advantages of git's repository over cvs's repository in this use-case are
not created because the branch is on the local machine. In fact, we also
created it on the server. The benefit comes from the git revision storage model
being faster and BETTER.

Then to switch our working pointer to this branch, we might do:

: "ncvs up -r mybranch" ->
:
: git stash; git checkout mybranch; git pull;
: git stash show --relevant --recent;

Our "safe update" automatically saved away any local directory changes before
switching off to the branch (if there were any). Our "stash show" is there
always to show us if any stashes hang off a recent parent of the tree we just
switched to, but it only shows them if they are hanging off this tree, and only
if they are recent. If there is, we might want to look at or grab it, or we
might just ignore it and not care.

(3) allow users to commit their 'final' changes to others (only on the branch
they are on)

: "ncvs commit" -> "git commit; git push <only this branch>;"

Question: how do I only push the branch I'm on? "eg" says it does this, but
from a quick look at the code, it wasn't obvious to me how.

Developers who are plenty happy with their existing model of never saving local
changes, can continue doing what they are doing. This makes the ability to save
local changes an added benefit to the users like me that want to do it, instead
of an extra burden to the other users. It also simplifies the issue of which
changes are pushed to the server and which are not, because pushing is managed
by "git push <only this branch>", not by creating and managing local and remote
branch names separately. (easy git took the same approach with push)

(4) Allow users to save interim changes, without ahead of time planning, ahead
of time nameing, and hopefully, without naming at all.

Saving interim changes in a cvs working tree before merging with head is not
cheap. Making my own branch tag isn't too hard, but it takes a long time on a
big tree. Ironically, perforce made branching mechanism faster while making the
cognitive load of branch hing much higher.

: "ncvs save" -> "git commit -a"
:
: "ncvs stash [$name]" ->
:
: $currentbranch = `git branch`
: $base-ish = '<baseof: current branch>'
: git stash;
: git branch -m $currentbranch $name;
: git checkout $baseish;
: git branch $currentbranch

This "ncvs stash" is acknowledging the value of the "git stash" idea, while
also recognizing that when I'm using "git commit" regularly, I don't have
anything in the working set! I really want to stash the changes made since
"origin/<branchname>" and return there with my local <branchname>. This is
really after the fact branch creation. If no $name is supplied, then it can
auto-generate one like stash does.

(5) make it obvious there is a difference between local and remote changes, but
make it easy to diff against remote before "ncvs commit;"

: "ncvs diff" ->
:
: echo -n "since commit(-C): "  \
:   `git diff --shortstat <baseof:current branch>`; \
:   echo
: echo -n "since save(-S): " \
:   `git diff`; echo
:
: "ncvs diff -S" -> "git diff"
: "ncvs diff -C" -> "git diff <baseof:current branch>
--------------------------------------------------------------

I'm primarily trying to understand how to map my model to git.
Continued thanks for the discussion and help.

```

## David Jeske, 2016-08-14 00:43

Subject: Re: policy and mechanism for less-connected clients
Message-ID: <willow-jeske-01l6ZD0vFEDjCXou>
URL: https://gitlist.dev/e/willow-jeske-01l6ZD0vFEDjCXou
In-Reply-To: <willow-jeske-01l6XqjOFEDjC=91jv>

```
Some answers thanks to Jakub...

-- David Jeske wrote:
> : "ncvs up" ->
> :
> : git stash; git pull; git apply;
> : git diff --stat <baseof:current branch> - un-pushed filenames
> : git-show-branch <current branch> - un-pushed comments
>
> Question: when I say "baseof:current branch", I mean "the common-ancestor
> between my local-repo tracking branch and the remote-repo branch it's
> tracking". How do I find that out?

I'm told I need...

git diff --stat `git-merge-base HEAD ORIG_HEAD`

> : "ncvs commit" -> "git commit; git push <only this branch>;"
>
> Question: how do I only push the branch I'm on? "eg" says it does this, but
> from a quick look at the code, it wasn't obvious to me how.

and...

git push HEAD


which just leaves this one....

Question: How do I create a branch on a remote repo when I'm on
my local machine, without sshing to it?

```

## David Jeske, 2016-08-14 00:43

Subject: Re: policy and mechanism for less-connected clients
Message-ID: <willow-jeske-01l6aDyTFEDjCfcn>
URL: https://gitlist.dev/e/willow-jeske-01l6aDyTFEDjCfcn
In-Reply-To: <7viqvxxix0.fsf@gitster.siamese.dyndns.org>

```
-- Junio C Hamano wrote:
> >> : "ncvs up" ->
> >> :
> >> : git stash; git pull; git apply;
>
> First of all, if you are in CVS mindset, you may not want to necessarily
> do "git pull", but "git fetch" followed by "git rebase".

I don't want to replicate CVS behavior, just the workflow. I've considered
rebase, but the diagrams on the documentation page look scarry. I want to keep
the dag-nodes made by their local git commit;. At those commits the code worked
and tested in their tree. rebase looks like it tosses those dag-nodes when it
rewrites the diffs -- who knows if the tests actually pass for every point
along that new rebase. That's no good.

I can see the use of rebase when your job is to "author an understandable
public source tree", but I'm working on SCM, where the goal is to be able to
reproduce the state of past successes reliably.

I want someone to be able to checkout what was actually in the user's local
client as they were working. Which means I think I want "fetch and merge" which
is pull. Did I get that wrong?

> I suspect the last one in the above sequence of yours is "git stash pop".
> Definitely not "git apply" without any argument which is a no-op.

I meant to type "git stash apply", but I think you're right, pop is what I
wanted.

> >> : git diff --stat <baseof:current branch> - un-pushed filenames
>
> "git diff [--options] origin..." (three-dots) is often used. This is a
> shorthand for:
>
> git diff [--options] $(git merge-base origin HEAD) HEAD
>
> that is, "show me what I did since I forked from origin".

I'm still a little foggy on the remote referenecs, but remember I have two
remotes (shared) and (personal). Something in the docs led me to believe
'origin' was repository wide, not private to each branch. Is "origin" a magic
name for the current branch's target?

> >> : git-show-branch <current branch> - un-pushed comments
>
> This would be useful if you are using "fetch + rebase", but in any case
>
> git log --graph --pretty=oneline origin..

Ahh, yes, Thanks!. How does this interact with the "pull" I just did?

What I want is "show me the commit messages (and sha1 keys) for changes in my
local branch that are not yet submitted to it's remote tracking location"

Will that command above include the commit lines that came down in my pull
(fetch/merge)? If so, how do I not include them?

> > Question: How do I create a branch on a remote repo when I'm on
> > my local machine, without sshing to it?
>
> I hope that the question is not "How do I do anything on a remote without
> having any network connection to it" as its answer cannot be anything but
> "telepathy".

Funny. I'm asking how I can run a command locally, that during the next "git
push HEAD" will cause a branch to be created on a remote repository, without
assuming that is the same repository that my current branch is pointing to.
Will this do the trick?

git branch --track mynewbranch git://myserver/path/foo.git
# hack hack
git commit
git push HEAD

- David

```
