LibGit2Sharp filter-branch like capabilities - libgit2sharp

I am looking to use LibGit2Sharp to write code to support a scenario we want to automate.
We want to create a new git repo from specific folders in an existing git repo while still providing history for the migrated folders.
So given:
sourcRepo/
folderA/
folderB/
folderC/
And if we choose folderB and folderC, then we want a new repo like the following:
newRepo/
folderB/
folderC/
Where newRepo has the full history of changes for folderB and folderC.
How can this be accomplished in LibGitSharp2?

Related

In Gerrit, how can I push arbitrary tags to non-standard locations?

I would like to push build tags to a non-standard location on gerrit, mainly to avoid them from showing up as an official tag and also to avoid polluting users with a bunch of build tags.
On old versions of gerrit, I was able to grant myself permissions to create refs and tags in, say, refs/builds/tags/*, and then do
git push origin refs/tags/BUILD-123:refs/builds/tags/BUILD-123
The beauty of the scheme is that this way, the build tags don't pollute ordinary users' git repos, but if someone is interested in the build tags, they can run:
git fetch origin 'refs/builds/tags/*:refs/tags/*'
and then all the build tags appear and become usable as tags.
It seems that on newer versions of gerrit (2.16?) direct push is limited to the standard locations.
It also appears as if one can only push tags of commits which are direct ancestors an existing branch, so if my build does anything unusual (for example rebase to the tip), it fails.
Is this configurable anywhere?
It turns out there is no such restriction, you just have to grant yourself all the required permissions, like so:
[access "refs/builds/*"]
create = <me>
createSignedTag = <me>
createTag = <me>
delete = <me>
read = <me>
I forgot to give myself read permissions...
The restriction that does exist is where you cannot push a tag that is not for a commit that is an ancestor of an existing known branch. The reason this restriction exists is because access to commits is controlled via ACLs that feature wild carded refs as primary key to permissions. If someone knew a "forbidden" sha and was allowed to push a tag, this scheme can be bypassed.
The trick is to give up on pushing tags and to push branches instead. Branches can be pushed to non-standard locations just like tags, and if someone fetches them into refs/tags, they also act like lightweight tags.

How to upload an image to use in issue comments via Github API

I'm currently working with Github API to make an iOS github client app.
I'd like to implement the feature of creating issues with images. My question is how to upload an image for issue comments via API. We're able to upload the image by drag-and-drop via browser in github.com like image below:
I'd like to use this https://cloud.githubusercontent.com/assets/~~~.PNG.
Any way to upload to https://cloud.githubusercontent.com via API or something?
By the Feb 2020 there are still no official solution to upload files via API to be used in the github issues.
Simple solution is to use a repository branch (you can name it assets). You can link to them from the github issues easily, just use raw link with last commit SHA:
https://github.com/ORG/REPO/raw/LAST_SHA/PATH
This kind of link will be rendered in the issues body always correctly.
Ever I also try to find one way to make it.But there is not any available method to do it. I'm doing some extra test to find that you can observe the drag-and-drop action in your devtool-network panel.
I find that https://github.com/upload/assets/21842410 be requested with PUT method, and its response is {"id":21842410,"name":"-2.png","size":1261,"content_type":"image/png","href":"https://cloud.githubusercontent.com/assets/3518853/21842410/7c3f6812-d79b-11e6-8209-e49b44aaa883.png","original_name":null}
I've not finished my test, if this inspires you and you have time to implement any demo, please tell me your result. :)
A solution I'm using is to push the images to the repository instead, and use a relative link in the issue.
You can create an orphan branch just for images and push it to a ref outside of refs/heads, this way this ref is not cloned in a normal clone (you would need git clone --mirror).
It would look something like this (proof-of-concept):
git checkout --orphan images
git rm -rf *
# copy your images to the repo
git add <your images>
git commit -m "add images"
git push origin HEAD:refs/images/image-ref
git log --format=%H
# note the hash
and then in the issue, use a relative link using the commit hash from above:
![alt text](../blob/<HASH HERE>/path/to/your/image.png?raw=true)
It can't be done. Your only chance is to upload your image to your own s3 bucket or similar and link that in the comment/issue. I think github will pick up those and cache them for better user experienceon github.com

Switch branches, keep same change-set

I have a change-set in Gerrit that for a while has been based off of the master branch.
So, my push commands have looked like this:
git push origin HEAD:refs/for/master
But now, I need to start working off of a topic branch (but still using the same change-set).
So, I tried pushing like this:
git push origin HEAD:refs/for/myTopicBranch
But, this seems to have created a whole new change-set, rather than simply altering the metadata of my current change (as updating a topic does).
Is there a way associate a change-set with a different branch after creation?
No. You can't do that. If you want to work in a different branch, push to this new branch like you have done (git push origin HEAD:refs/for/myTopicBranch) and abandon (using the Gerrit web interface) the original change.

How to assign access rights to a Gerrit project using API / SSH?

I'm looking for a way to automatically add +2 permissions for certain refs for a lot of projects in Gerrit and unfortunately it seems there are no API calls to modify access rights, only to read them. Do you have any idea how to modify refs permissions for a big amount of projects?
I'm using Gerrit 2.9.
Thanks.
One possibility would be to create a batch script to modify the project.config for those projects and commit them back to gerrit.
This is how you can checkout the project.config for the All-Projects, it works the same for other projects: http://blog.bruin.sg/2013/04/how-to-edit-the-project-config-for-all-projects-in-gerrit/
Simply put:
Create list of project you want to change
Iterate over the lest
Checkout the refs/meta/config ref
Use script to modify project.config
Commit and push back to the server
More information about the project.config: http://gerrit-review.googlesource.com/Documentation/config-project-config.html

How to keep public and private versions of a git repo in sync?

I'm releasing an open-source Rails app on Github (probably MIT license). I also want to maintain a private branch/fork of the project that we will use as part of a pay service.
What is the best way to organize the repo(s) in this scenario? And, how can I keep the projects in sync when I have updates that should go to both?
The simplest solution would be to have private branch in your 'private' repository, i.e. branch which is simply not pushed to public repository.
For that you would probably need to either specify all branches you want to push to public repository in config (instead of using globbing mirroring refspec +refs/*:refs/*), or push carefully branches you want to publish and rely on Git behaviour of pushing matching branches (those which are present on remote side) setting "push.default" to current default value "matching".
If you by accident push your private branch, you can delete it in remote repository (unless it is configured to forbid this) using "git push <remote> :refs/heads/<private-branch>" (to remember this: push empty value to remote branch). You can protect against accidental pushing of your private branch using hooks on remote side, see e.g. update-paranoid example hook in contrib/examples.
Sidenote: Junio C Hamano, git maintainer, pushes to public git repositories only specified set of branches: 'maint', 'master', 'next', 'pu' (proposed updates), and 'html', 'man', 'todo'; he does not publish short-lived often changing feature branches.
EXAMPLE SETUP:
working repository ----> private repository (bare) ----> public repository
\------ private -------/ \------- protected ------------/ \------- public -----/
"Working repository" is the repository with working area that you make commits in, where you pull changes and resolve conflicts; repository where you do your work. Let's say it contains the following branches: 'public' with changes that can be published to the world, 'private' that you want to not share with others or share only with selected subset of people, and perhaps some feature branches like 'ticket-234' or 'add-frobnicator', which are not ready even for selected group to see. This repository is non-bare, as it not published.
It would have something like the following configuration for pushing to 'private' repository. Note that "matching branches" behavior is set explicitely here, see git-pull manpage:
[remote "private"]
url = user#example.com:/srv/private/git/repo.git
push = +:
"Private repository" is public bare repository available only to selected people, for example it is available for fetching only via SSH. It has only branches which are ready, i.e. 'public' and 'private' branches; either those branches were present when creating "private" repository, or were pushed explicitely ("git push private <branch>") from "working" repository. Push from "working" repository pushes (transfers) only matching branches, i.e. only 'public' and 'private' branches.
"Private repository" has post-update or post-receive hook set which pushes 'public' branch only to "public repository" (see below) if it was pushed to it (well, it can push unconditionally).
"Public repository" is public bare repository available to everyone, for example it is hosted on GitHub, and/or Gitorious, and/or repo.or.cz, or perhaps it is served via git:// protocol using git-daemon. It contains only 'public' branch, and it uses update or pre-receive either to accept whilelist of branches (here only 'public' branch is accepted), or reject blacklist of branches (in this example pushes to/creating 'private' branch would be rejected). It is updated automatically when pushing to "private" repository.
This setup might be overly complicated for your needs; "private" repository might be not necessary in your case. In such case the configuration in "working repository" for pushing directly to "public repository" would look like this:
[repository "public"]
url = ssh://example.com/srv/git/repo.git
push = refs/heads/public:refs/heads/public
I hope this example would help; please however read the documentation and do not use it blindly.
If the code regarding the "part of a pay service" is separate (i.e. "in another directory") than the code representing the "open-source Rails app" pushed to public repository, you could:
defined the public part as an independent repository (that you can push whenever you need to)
defined the private part as another independent repository
use submodules to include your public part within your private repository
That way, you are working with the all system (public Rails app + private pay system), but only push the public part to GitHub, and you can push the all system (private + public) to another private repository (on a backup machine for instance).
If the private code is mixed with the public one... then see Talljoe's answer or Jakub Narębski's answer.

Resources