[git-users] multi workspace solution

2013-10-03 Thread pof Andras
Hi all,
I would like to implement a multi-workspace version of git. 
The main goal is to have several independent workspaces using only one and 
single repository (without their own cloned repos). All these things will 
run on one host, or probably will be located on nfs and will be available 
on more hosts. Yes, I know there should be some restrictions, for example 
push and pull will work on the repo (probably there can be something like 
my-push). Branches will be somehow tied to the workspaces, also all 
workspaces will have its own HEAD. 

I would like to discuss here how can it be implemented, what will (or will 
not) work.

Thanks for all the tips and hints.

Andras

-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


[git-users] moving top of branch to another repository

2013-10-03 Thread ruud
hi group,

I recently started a new branch in a project. It appeared that the branch 
only contained new software and was not based on the rest of the project.
I want to move that branch to a new repository, but not all of the history 
of the original project. I found out with the help of google, it is 
possible to git-push a branch to a new repository, but then all the history 
of the project comes with it, not only from the point where the branch 
started.

A-B-C-D
 \ E-F-G

Both D and E-F-G are based on C. I only want to move E-F-G to a new repo

The best I can think of is this:
* git push the branch to a new repository (giving A-B-C-E-F-G)
* with git-rebase delete all of the old project commits A-B-C

Is this the only way?

thanks in advance, Ruud

-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [git-users] multi workspace solution

2013-10-03 Thread Konstantin Khomoutov
On Thu, 3 Oct 2013 01:28:03 -0700 (PDT)
pof Andras porje...@gmail.com wrote:

 I would like to implement a multi-workspace version of git. 
 The main goal is to have several independent workspaces using only
 one and single repository (without their own cloned repos). All these
 things will run on one host, or probably will be located on nfs and
 will be available on more hosts. Yes, I know there should be some
 restrictions, for example push and pull will work on the repo
 (probably there can be something like my-push). Branches will be
 somehow tied to the workspaces, also all workspaces will have its own
 HEAD. 
 
 I would like to discuss here how can it be implemented, what will (or
 will not) work.

That was implemented long time ago in the form of the git-new-workdir
script available in the contrib Git subdirectory [1].
The basic idea this Unix shell script implements is to create a separate
directory with .git subdirectory in it which links to the real one
*but* leaving intact things like HEAD which are purely local.
This allows to have any number of separate checkouts of different
branches, all referring to a single repository.

Note that this script won't work on Windows as it makes use of symlinks
which doesn't play together well with Windows.

1. https://github.com/git/git/blob/master/contrib/workdir/git-new-workdir

-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [git-users] moving top of branch to another repository

2013-10-03 Thread ruud


On Thursday, 3 October 2013 11:51:28 UTC+2, Konstantin Khomoutov wrote:

 I think yes, this is the only way because you need to squash A-C into a 
 new commit, C', and then reapply E-G on top of it, and that's what 
 `git rebase` is goot at. 


Hi Konstatin,

thank you for your reply. I was a bit afraid this was the way to go. If I 
focus on first pushing the whole of the branch A-G to a new repository: 
when I squash A-C into commit C', it still leaves me with a commit isn't 
it? Although I need no single file in that commit. I can empty it, but it 
still leaves me with that node. 
No possibility to make E the root node of the repository?

regards, Ruud

Note that you might as well do squashing in the original repo and then 
 push the modified history: first fork a new branch off G, then rebase 
 it, then push, then delete. 


-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [git-users] moving top of branch to another repository

2013-10-03 Thread Konstantin Khomoutov
On Thu, 3 Oct 2013 03:56:03 -0700 (PDT)
ruud r.grosm...@gmail.com wrote:

  I think yes, this is the only way because you need to squash A-C
  into a new commit, C', and then reapply E-G on top of it, and
  that's what `git rebase` is goot at. 
 
 thank you for your reply. I was a bit afraid this was the way to go.
 If I focus on first pushing the whole of the branch A-G to a new
 repository: when I squash A-C into commit C', it still leaves me with
 a commit isn't it? Although I need no single file in that commit. I
 can empty it, but it still leaves me with that node. 
 No possibility to make E the root node of the repository?

Sure it's possible: just squash A-E into E' not A-C into C' -- there's
really no difference, I've just failed to discern from your message
that you did not want C as well.

If you'are worried by the fact D references C as well as E, and that
squashing A-E would affect D, then fear not: parental relation between
commits is implemented in reverse -- children refernce their parents
while parents do not know anything about their childen, -- and
`git rebase` creates new commits not *replaces* those which were
created when rebasing so your

A-B-C-D - foo
 \ E-F-G - bar

(with foo and bar being refs (tags or branches) pointing to their
respective commits) after squashing A-E into E' and rebasing F-G onto E'
would look like

A-B-C-D - foo
E'-F'-G' - bar

That is, D will reference the same chain of commits as before while
bar will reference a new chain with all new commits; E' will be
synthetic and F' and G' will be mostly the same as their original
commits F and G but with their commit dates changed.

Let's recap: when `git rebase` creates new commits, old ones are left
intact and they either persist (if they're still referenced by a ref)
or become dangling and are eventually garbage-collected.  They're not
*replaced* in the sense of being modified in-place; they're replaced
only from the point-of-view of a reference which has been rebased and
now points to a new chain of commits.

Note though that there's no such thing as a root node of a
repository: a Git repository might contain arbitrary number of branches
which share no commits (and even no other kinds objects such as trees
and blobs).  So the correct spelling would be a root commit of the new
branch.  That's nitpicking, but I thought it won't hurt clarifying to
possibly prevent future confusion.

-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [git-users] Re: keeping two bare repos in sync?

2013-10-03 Thread Konstantin Khomoutov
On Wed, 2 Oct 2013 12:04:28 -0700 (PDT)
dkoleary dkole...@olearycomputers.com wrote:

 Apologies for replying to my own post, but I did just find the git
 --bare fetch.  While that seems to have worked, 

That's odd: `git fetch` does not support --bare, only `git clone`
does.  If `git fetch` doesn't fail on this option, it's a bug, I think.

 # git --bare fetch ${prod}:/opt/app/git/filemover
 From ${prod}:/opt/app/git/filemover
  * branchHEAD   - FETCH_HEAD
 
 how do I go about getting those changes into the bare repo?  A git
 log isn't showing the new commits yet...

Well, it's all in the refspecs.  The refspec if short for ref
specification and ref is a short form of reference in Git's
parlance.  A ref is a symbolic name pointing to an object in the Git
database; branches, tags and notes are all example of refs.

Refspecs tell certain Git commands on which refs to operate, and how.
For instance, the full form of the `git fetch` call is

git fetch [OPTIONS] [remote [refspec ...]]

where remote is either an URL or the name of a named remote (those
managed with the `git remote` command).

Now let's cite the `git fetch` manual:

  refspec

The format of a refspec parameter is an optional plus +, followed
by the source ref src, followed by a colon :, followed by the
destination ref dst.

The remote ref that matches src is fetched, and if dst is not
empty string, the local ref that matches it is fast-forwarded using
src. If the optional plus + is used, the local ref is updated even
if it does not result in a fast-forward update.

and earlier there:

The ref names and their object names of fetched refs are stored
in .git/FETCH_HEAD. This information is left for a later merge
operation done by git merge.

The missing bit of information is that if Git fails to obtain a refspec
-- there's no refspec on the command line and none can be obtained from
the local repo configuration (more on this later) it assumes you want
to get whatever HEAD ref points in the remote repo, that is, if no
refspec is available Git uses HEAD, literally.

Now let's put the parts of the puzzle together: a call

git fetch URL

is turned out to be

git fetch URL HEAD

since no refspec is available.  Now Git contacts the repository at
URL, fetches whatever HEAD points there (in bare repos it's usually
refs/heads/master), writes all the objects fetched into the local Git
database and then writes the SHA-1 name of the fetched tip commit into
a special ref FETCH_HEAD.  No local branches are updated as the result
as there's nothing in the default refspec which tells Git to do so.

Now if you want to fetch all tags and branches from the remote repo and
update everything with matching names in a local repo, you'll have to
be clear about this:

git fetch URL '+refs/*:refs/*'

which means grab every ref from the remote side and update
corresponding refs locally with the fetched data.  I used single
quotes deliberately as you had to protect asterisks from being expanded
by the Unix shell.  A plus sign is there to force owerwriting the
local refs if the remote history changed in a non-linear way since the
last fetch.  If you only need branches (called heads in Git lingo) and
tags (but not notes, for instance), use several refspecs:

git fetch URL '+refs/heads/*:refs/heads/*' '+refs/tags/*:refs/tags/*'

This information by itself is already a solution to your problem, but
let's dig deeper.

A part of the magic `git clone` does is to set up a single named
remote called origin.  Setting up a named remote means creating a
special section in the configuration of a local repository -- in the
file named .git/config (or just config in a bare repository).
This section looks like this:

[remote origin]
url = REPO_URL_PASSED_TO_GIT_CLONE
fetch = +refs/heads/*:refs/remotes/origin/*

Notice the fetch variable there which defines a refspec for
`git fetch` (and, by definition, for `git pull` as well).
I copied this section from the configuration of a non-bare repo so you
might notice that the right-hand side of the refspec (what to update)
speficies refs/remotes/origin/* and not just refs/heads/*.  That's
because in non-bare repos `git fetch` by default updates the so-called
remote branches, and not your own local branches you're working on.

Now when you call `git fetch origin` (or just `git fetch`) in a
repository set up like this, Git sees no refspec passed to it on the
command line and so it looks up the remote.fetch configuration
variable in the local repo (in this case it will be origin.fetch), and
if it's found, uses the refspec it defines.  Note that contrary to the
default refspec, HEAD, this one set up by `git clone` actually
specifies what to update with the fetched data.

Now let's turn to `git clone --bare`.  As specified in its manual page,

  --bare

Make a bare GIT repository. That is, instead of creating
directory and placing the administrative files in

Re: [git-users] Re: keeping two bare repos in sync?

2013-10-03 Thread dkoleary
Hey;

Absolutely amazing, sir!  Your answer is spot on accurate, very complete, 
and very detailed. While I sorry that I put you to that much unpaid work, I 
am very grateful.  I'm going to bookmark this explanation and refer to it 
regularly until the concept sticks.  I have a grasp on it now; but, I'm not 
sure it's completely there yet.

Some interesting data points that will probably be explained by different 
git versions or the fact that I'm cloning from a bare repo:

* ``git clone --bare ${prod}:/${dir}`` results in a bare clone, obviously. 
 The config file, though, doesn't have the remote origin stanza to which 
you referred, nor does ``git remote -v`` display anything.

# cat config
[core]
repositoryformatversion = 0
filemode = true
bare = true
# git remote -v
#

*  Easily added and, once done, run the git config command you mentioned 
results in:

# git fetch -v
From ${prod}:/opt/app/git/filemover
 * [new branch]  master - origin/master
 = [up to date]  master - master
# git remote -v
origin  ${prod}:/opt/app/git/filemover.git (fetch)
origin  ${prod}:/opt/app/git/filemover.git (push)

* Updating a file, pushing to the prod repo and then fetching from the DR 
one work flawlessly.

Thank you again for the very clear, concise, and accurate answer.  

Doug O'Leary

-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [git-users] Git-Enforced Policy

2013-10-03 Thread jobj92
Thanks for the reply.

On Thursday, October 3, 2013 6:29:16 AM UTC-4, Konstantin Khomoutov wrote:

 On Wed, 2 Oct 2013 13:36:42 -0700 (PDT) 
 job...@students.rowan.edu javascript: wrote: 

  I am trying to prevent users from attempting certain operations on my 
  repository which is located on a Linux server by employing 
  Server-Side hooks. The Git manual recommends creating a shell wrapper 
  script to set a USER environment variable, which will then be used to 
  restrict certain permissions. I looked for the better part of 
  yesterday for a guide on how to do this (*as I'm new to both unix and 
  git*), but was unable to find anything definitive. So I started 
  piecing things together and trying different options. 

 First, can't you just install gitolite [1] and make it handle 
 everything for you automagically?  It supports virtual Git users (that 
 is, it requires only a single account in the system while individual 
 developers authenticate using their own SSH public keys, and are 
 distinguished based on this; by the way to implement this it uses the 
 same feature of the authorized_keys file you're attempting to exploit) 
 and provides for per repository- and per-branch access controls, 
 including groups of developers etc.  Both access rules and developers' 
 public keys are managed using a special administrative Git repository. 


From what I read Gitolite license isn't commercial, and we're also trying 
to avoid using third party software for this implementation (even though it 
would make things easier).
 


  After wasting 
  close to two days now I am sitting at a solution I feel should work, 
  but am unable to actually clone a directory at. 
  
  I have defined the following bash script: 
  #!/bin/bash 
  export USER=$1 
  /bin/bash 
  
  In the authorized_keys file I call this script with a user parameter 
  whom would be logging in. At this point, git would use the update 
  script (which is not currently in place) and do whatever it needs to 
  do. However I've been attempting a basic clone and I'm stuck at the 
  command line after the .git folder has been created, and before any 
  files have been brought down. Can you link me to a guide for this or 
  explain what I'm doing wrong? 

 Well, could you explain this in a bit more detail? 
 Does the repository you're attempting to clone have any commits 
 recorded in it?  Does Git client errors out when cloning? 

 There are commits and I'm not receiving any errors while cloning, it just 
sits with a blinking cursor and no prompt.
 

 Next, I fail to see why Git would use the update script (do you mean 
 hook?) if you do cloning?  An update hook script, if present, is called 
 by Git which is receiving changes which are being *pushed* to the 
 repository by another Git process; when you clone, this does not happen 
 as you're *fetching* the changes. 


Yes, I suppose that the update hook wouldn't be run here. However I fail to 
see why setting an environment variable is causing the clone operation to 
hang. I suppose the process I'm going about isn't the appropriate one for 
this task, so I will go about trying to revert my changes.
 

 In the end, I suspect you're on a wrong track: hooks are there to 
 affect Git's behaviour but they do not implement the behaviour. 
 I mean, when you push commits to another repository via SSH, a special 
 process, git-receive-pack, is spawned on the remote machine, and then it 
 communicates with the git-send-pack process running on your local 
 machine; they communicate over the tunnel set up by SSH.  Hooks are 
 called at key points of git-receive-pack's transision through its 
 action sequence defined by the exchange protocol.  So if you want to 
 subvert git-receive-pack (that's what you're trying to do, as I 
 understand) then you should employ forced commands in your 
 authorized_keys file, and that forced command should be a script which 
 ultimately calls $SSH_ORIGINAL_COMMAND after performing the require 
 setup.  Refer to the authorized_keys manual page. 

 Ah I believe I'm starting to understand. By executing SSH_ORIGINAL_COMMAND 
the server will execute the process that I interrupted with my script? 
That's certainly helpful to know! 
 

 1. https://github.com/sitaramc/gitolite 


As an aside, the ultimate purpose of this is to work in accordance with a 
program I'm developing using jgit that will update my clients software by 
keeping an up to date copy of the compiled code in their local repo. Is 
this something that people in the industry do, am I opening myself up to 
vulnerabilities, or is this overly complicated? This is why I'm trying to 
disable pushes by anyone except the compilation server using the update 
hook. I haven't done much research yet on this next bullet point, but is it 
possible to limit customer specific code? IE, If I have a repository with 
100 folders and 100 users, can I make it so that each user only has access 
to one of these folders on a clone or pull?