it's a pretty new thing to me. We have admitted our customer to get access to our source code. Using bitbucket/Sourcetree i meant to use a Fork to grant him read Access to a given state/commit. I don't want to grant access to actual (still in development code). I plan to share milestones only. Can Forks be used in this manner? Are there other options to share particular commits only? BR, Daniel
For what I think you want to do, the simplest way would be this:
.git
hidden dir); This way, client will see a snapshot of your code. No current commits and no history.
I don't believe there's a way to provide commit- or branch-level access control within a repo. Creating a more limited repo is a reasonable approach, but depending on your needs I would possibly suggest some alternatives to copying the snapshot in the way Sergio Tulentsev suggests.
The potential downside to that is the loss of any data that would internally connect the shared snapshot back to your history. If you might provide new versions in the future, or if you might accept patches from the fork back into your codebase, then this separation creates additional work.
Part of the solution is simply keeping track of the relationships between your commits (with history) and their commits (provided snapshots); and that part of the problem you could solve just with a tagging convention of some sort. But beyond that, if you think you might want to migrate changes back and forth then you can set things up to avoid some manual migration work.
So you could try something like this:
First, in your repo, identify the commit you initially want to share and create a branch for the fork. If you have the commit tagged as commit-to-be-shared then
git checkout commit-to-be-shared
git checkout -b fork_master
(Or maybe the customer's name instead of fork-master
, if you think this is something you might do again for someone else...)
Next, instead of manually copying to a new repo, make a "shallow clone" of your origin. Note that you must use a URL (not a local path); so if you normally address the repo as /path/to/my/repo
use something like file://path/to/my/repo
... details depend on your OS, but hopefully you see what I mean...
cd ..
git clone --depth=1 -b fork-master http://my.server/origin-repo
This will only copy the one commit, and will set up fetch to only retrieve the fork-master
branch. But , it will preserve the identity of the commit. So in your origin, in the future you could merge more changes into fork-master
and easily share the resulting commit. BUT if/when you do push more changes, see below for notes on avoiding unintentional history exposure.
Next you prepare an empty repo on your server (along side your origin) which will serve as the customer's origin. Then set it up as a second remote in your newly created shallow repo:
git remote add fork-origin http://my.server/fork-origin-repo
git push -u fork-origin master
(Again you could use a customer-specific name for the remote if you think you might have more later...)
Any of your developers can add fork-master
too if you want to allow it, and in this way you can seamlessly receive patches from the customer.
There is a trick to ensuring you don't inadvertently expose history in the future, though. When you make a future merge to fork-master
and deliver it to the fork-origin
, by default it would bring the history of the newly-merged commit. The apparent simple fix is, in your shallow repo:
git pull --depth=1
The problem here is that git can become confused. (Short explanation is that the newly-fetched merge is meant to have depth 1 on the 2nd parent but not on the first, and git doesn't seem to handle that the way you might hope.) Not too hard to solve:
git pull --depth=2
Now you'll see, though, that the merge brought one extra commit of history from the newly-merged-in work. That commit just contains the changes you're merging in to fork-master
so it probably is ok; but maybe that commit has a commit message, or tags, or something else that you don't necessarily want to share. In that case, you could always create a sort of "buffer commit" just before the merge.
F1 -------- F2 <--(fork-master)
/ /
/ B
/ /
X ---- X --- A --- X <--(master)
where F1
is the original shared snapshot, A
contains more changes you've decided to share, B
is a "customer-safe" commit that essentially duplicates A
, and F2
is the new merge. Then the customer would see
F1 ---- F2
/
B
You may have to use the --allow-empty
option when calling git commit
to create B
.
Note I haven't had a chance to test this end-to-end; if you get errors at any step please let me know so I can update accordingly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.