github "Automatically delete head branches" for multiple repositories - github

On Github we can set automatically deletion of branches after merge for a repository (like explained here). I want to do this for 30 repositories.
Is there a way to do this by script ?
I typically would like to add a file to each repository.

I think you can do this relatively easily with a script. You can use the GitHub CLI for this. There is the following command with which you can switch on the deletion of the branch after a successful merge for a repository:
gh repo edit [<repository>] --delete-branch-on-merge
If you want to start with the CLI, I guess this is a good starting point.

Related

From github CLI, how to change from local repo to a repo on a differnt server, to create issue on that repo?

I am new to GitHub Command Line Interface (CLI).
From the github command line interface, I'd wanted to create an issue, but mistakingly selected a local repo intead of the repo from which I forked from. So how can I change from the local repo to the repo from a different server, where I forked and cloned from, please?
gh issue create --web is an interesting alternative, because by opening the GitHub issue web page, you would immediately realize you are not on the right repository.
As commented, you would need to use the -R option to reference the upstream repository (as opposed to the default one)
Make sure to use the latest gh version though, at least 1.60 or more, since gh issue create -R used to ignore issue template before. (issue 2361)

GitHub - Pull changes from a template repository

I have created a Template Repository in GitHub and then created some repositories based on the template. Since they were created, there have been updates to the template that I want to pull into those repositories.
Is this possible?
On the other repositories you have to add this template repository as a remote.
git remote add template [URL of the template repo]
Then run git fetch to update the changes
git fetch --all
Then is possible to merge another branch from the new remote to your current one.
git merge template/[branch to merge] --allow-unrelated-histories
https://help.github.com/en/articles/adding-a-remote
I will link to the same location as HRK44 but my answer is very different.
https://help.github.com/en/articles/creating-a-repository-from-a-template
Although forks and templates are mentioned in the same section, they are very different.
One of the differences mentioned in the link is:
A new fork includes the entire commit history of the parent repository, while a repository created from a template starts with a single commit.
This basicly means that you will not be able to pull new changes from the template as your git histories are very different and are not based on the same thing.
If you do use the method mentioned in the accepted answer, you will have very hard manual merges that will result in changes to all of the files received from the template, even if they werent changed since the first time you created that repo from that template.
In short, creating a repo from a template (using only master branch) is the same process as:
git clone template
cd folder
rm -rf .git
git init
git remote add origin <new repo url>
git add .
git commit -m "Initial Commit"
git push -u origin master
A few other things that are not (surprisingly) copied when creating a repo from a template:
(Unless github fix this at a later point)
Repo configurations (allowed merge types, permissions etc)
branch rules
So when using this at your organization, make sure to set all repo configurations on the newly created repo.
If you want to merge changes from a template into your project, you're going to need to fetch all of the missing commits from the template, and apply them to your own repo.
To do this, you're going to need to know the exact commit ID that you templated from, and you're going to need to know the commit ID of your first commit.
ORIGINAL_COMMIT_ID=<commit id from original repo you templated from>
YOUR_FIRST_COMMIT=<first commit id in your repo>
YOUR_BRANCH=master
Next you're going to need add the template as a remote, and fetch it.
git remote add upstream git#github.com:whatever/foo.git
git fetch upstream
And finally, you need to rebase all of the commits you're missing onto your branch
git rebase --onto ORIGINAL_COMMIT_ID YOUR_FIRST_COMMIT YOUR_BRANCH
What this is doing it basically creating a branch off of ORIGINAL_COMMIT_ID, then manually applying all of the commits on your original branch, onto this new branch.
This leaves you with what you would have had, if you had forked.
From here, you can git merge upstream/master just as if you had forked.
Once you've completed your merge, you'll need to use git push --force to push all of the changes up to the remote. If you're working with a team, you'll need to coordinate with everyone when doing this, as you're changing the history of the repo.
Note: It's important to note that this is only going to apply to one branch. If you have multiple feature branches, you'll need to perform the same steps to each one.
#daniel's answer also did not work for me because of the unrelated histories problem mentioned in #dima's answer. I achieved the desired functionality by doing the following:
Copy the URL for the template repository you wish to use to create a new repository. (ex: https://github.com/<username>/my-template.git)
Use GitHub Importer to make a new repository based on the template repository.
This solves the unrelated histories problem because it preserves the entire commit history of the template repository.
You need to use the Importer because you cannot fork your own repository. If you want to use someone else's template repository, you can just fork theirs.
Then, add the template repository as a remote.
git remote add template https://github.com/<username>/my-template.git
After you make new commits to the template repository, you can fetch those changes.
git fetch template
Then, merge or rebase. I recommend to merge on public repos and rebase on private repos.
To merge
git checkout <branch-to-merge-to>
git merge template/<branch-to-merge>
To rebase
git checkout <branch-to-merge-to>
git rebase upstream/<branch-to-merge>
NOTE: When rebasing, you must
git push origin <branch-name> --force
in order to override your old commits on your remote branch. This is why I recommend to rebase only on private repos.
I approached this differently as fetch & merge was not ideal as lot of files diverge across template and downstream projects. I only needed the common elements to sync.
lets says we have the below folder structure locally:
repos
├── template_repo
└── downstream_repo
1. Now create a git patch from the parent folder (repos):
git diff --no-index --diff-filter=d --output=upstream_changes.patch -- downstream_repo/some_common_path template_repo/some_common_path
NOTE - the order of the paths matters!, downstream_repo comes first! (interpret this as "what are the changes we need to make to downstream_repo to make it same as template_repo"; look at the --name-status output, it will hopefully make sense.)
--no-index option generates git diff based on filesystem paths. Path can be a single file or a folder.
--diff-filter=d will ignore any files that are in the downstream_repo but not in the template_repo. This only applies when diffing folder paths.
You can use --stat, --name-status to see what the patch will contain.
Review the generated patch.
2. Change to downstream_repo folder and apply the patch
git apply -p2 ../upstream_changes.patch
explanation for -p<n> option from the official doc:
Remove leading path components (separated by slashes) from
traditional diff paths. E.g., with -p2, a patch against a/dir/file
will be applied directly to file. The default is 1.
Using -p2 will drop a/downstream_repo and b/template_repo from the diff paths allowing the patch to apply.
This is the reason for starting with above illustrated folder structure.
Once the patch is applied, rest of the process should be familiar.
All of these options are clearly explained in git diff and git apply official docs.
Another option is to create a patch from the necessary commits and move the patch to a new project
git format-patch -1 HEAD
Insert a patch
git am < file.patch
details are here
I ran into this same issue. I have 10+ projects all created from the same template project (react-kindling) and using git alone wasn't sufficient, as it would pull in changes to the template that I didn't want in my child projects.
I ended up creating an npm utility for updating child projects from template starter projects. You can check it out here:
LockBlocks
It's been a real life saver. Pulling changes from the template is a heck of a lot easier now.
This works too:
git remote add template git#github.com:org/template-repo.git
git fetch --all
git merge template/main --allow-unrelated-histories

Importing a source code repository from AWS Code Commit into Github

We are using AWS Code Commit for source code and considering moving to Github in the near future. What is the easiest way to accomplish this ? I have seen a lot of articles about importing a Github project into AWS Code commit but not the other way around.
Simplest way is to clone your code commit repo and push it to your GitHub repo.
I think this is a very fair question and none of the comments have addressed it. Though it is trivial to migrate the git repo, that is not a full clone of all meta data related to it. This is roughly:
git clone --mirror <source repo>
Create new, empty repo in a GitHub org you can write to
git add remote target <dest repo>
git push --mirror target
What gets missed doing git migrations like this is things such as users/groups permissions, pull requests, secrets, and probably other things I've forgotten. This meta data is not stored in the git repo and needs to be re-implemented on the GitHub side. As there are usually APIs to the Git systems, migration scripts can be written and some are written by GitHub, some by individuals (though I struggled to find any active examples).
I too have searched extensively for a migration tool that actually gets all the data for an AWS CodeCommit repo and reproduces it as a GitHub repo.
It looks like I should be able to write a script that uses the AWS REST API to get the data and then write it to the GitHub API. I was hoping this code already existed and I would save a bunch of time writing and debugging it.

Un-fork GitHub project into new GitHub project not associated with the original [duplicate]

How can I make GitHub forget or disassociate that my repo was originally a fork of another project?
I forked a project in GitHub. I can now see "forked from whatever/whatever". The parent repository "whatever/whatever" is no longer maintained. I have been allowed to continue use of the code base of the original repository to create an independent repository.
Is there a way to detach my project from the original repository?
Update Jan 2022:
Use the GitHub chatbot-virtual-assistant at https://support.github.com/contact?tags=rr-forks&subject=Detach%20Fork&flow=detach_fork
First answer:
You can contact github support and ask them to switch your repository to "normal mode".
On this page, "Commit was made in a fork" paragraph, it is explained that one has to go through support to switch. Therefore, it is likely that there is no way to do that by yourself (unless you destroy and recreate your repo which is explained before... if you do so be careful if you have tickets or a wiki attached to your project as they will be deleted!).
You could duplicate the forked repository to a new repository (without the fork dependency) from the GitHub UI, then remove the original forked one:
Sign in to GitHub
Select the + sign in the top right corner and select Import repository.
Import your forked repository. The new repository won't have the fork dependency.
Delete the original, forked repository in the repository settings.
NOTE: This approach will not preserve issues and pull requests.
Make sure you have all the important branches and tags on your local repo, delete the github repo, recreate the repository through usual means (no forking) and push the local repository back with git push --all. Note that if you have local branches that you don't want to publish, might be worth to create a temporary clean local clone for the operation.
However, this will also get rid of wiki and issues. As the wiki is in fact it's own repository, it can be handled similarly by cloning it and then recreating and pushing. The repo address is on wiki's Git Access page (git#github.com:user/repo.wiki.git).
This leaves issues. They can be exported through the API, but as far as I know, you can only create issues and comments with your person, so importing them perfectly is impossible.
So, if you need issues to be preserved, you should go through github support as Thomas Moulard suggests.
I got the similar problem, and ended up using this github help page to solve it. I didn't mind about the wiki and issues tracker as it was for my blog using a theme kindly developed by another user.
To detach a forked repo and use it as your own after several commits without losing the whole history:
git clone --bare git#github.com:user/forked_repo.git
Create a new empty reposity new-repository on the github website.
And push a mirrored version:
cd user.github.com.git/
git push --mirror git#github.com:user/new-repository.git
One can rename on github, the forked_repository with another name to keep it as backup and check updates if needed. Or simply delete it.
Renaming the new-repository to the original name does the job. As a side effect, your commits now appear in your history.
Log in to GitHub with your credentials.
Go to https://support.github.com/contact?tags=rr-forks&subject=Detach%20Fork&flow=detach_fork.
Choose "Detach", then enter the URL or repo name of the fork as your-user-name/repository-name, and answer the other questions of the virtual assistant.
You will get an email with a ticket number where you can check the status of your request. You will also be notified per email once your repo has been deforked.
Most repository settings will stay unchanged, including user permissions, stargazers, issues, PRs, discussions, etc.
Using the info from aurelien and Clayton, I was able to do this with the following:
$ git clone --bare https://github.com/my/forked_repo.git
<delete forked_repo on GitHub>
<recreate repo on GitHub using same name>
$ cd forked_repo.git
$ git push --mirror
Here's the documentation for git clone --bare:
Make a bare Git repository. That is, instead of creating <directory> and placing the administrative files in <directory>/.git, make the <directory> itself the $GIT_DIR. This obviously implies the -n because there is nowhere to check out the working tree. Also the branch heads at the remote are copied directly to corresponding local branch heads, without mapping them to refs/remotes/origin/. When this option is used, neither remote-tracking branches nor the related configuration variables are created.
Here's the documentation for git push --mirror:
Instead of naming each ref to push, specifies that all refs under refs/ (which includes but is not limited to refs/heads/, refs/remotes/, and refs/tags/) be mirrored to the remote repository. Newly created local refs will be pushed to the remote end, locally updated refs will be force updated on the remote end, and deleted refs will be removed from the remote end. This is the default if the configuration option remote.<remote>.mirror is set.
Note: like the other git based answers, this will not copy over issues that are not part of the git repo such as the wiki and issues. Per Tapio:
The wiki is a separate git repo and can be handled in a similar fashion per Tapio. The address is: git#github.com:user/repo.wiki.git.
Issues can be exported via the GitHub API but there are issues recreating them since they can only be created by your user, so imports will lose information.
This only applies to GitHub Enterprise, not on github.com
Logged in to an account that has admin privileges:
Go to the repository that you need to detach: https://<ghe url>/<org>/<repo>
Click on the “Site Admin” rocket on the top right corner
Click "Collaboration" on the top menu bar
Click on “Network” on the left pane
Click on “Make Root” in the Network Structure pane
Accept
This was tested on GitHub Enterprise 2.9
If you do not need any past commits (I didn't in my case), you can just:
fork the project
make a local copy of the fork (I used my IDE to do that)
delete the git folder from your local copy
commit the project as you normally would a new project.
You can just delete the fork from your github account after. Took me all of one minute and worked like a charm.

Creating an official github mirror

How do I create a github mirror for an external git repository, such that it appears as "real mirror", e.g., as in https://github.com/mirrors?
So far, I set up a mirror using:
cd /path/to/bare/repository
git remote add --mirror github git#github.com:user/repo.git
and configure the post receive hook to do a git push --quiet github. This way, however, github does not recognize the mirror.
Any ideas how to do it the github way, such that "Mirrorred from" appears underneath the repostiory name?
Based on communicating with GitHub's support team, I found that GitHub currently offers no direct mechanism for a user to mirror repositories in this fashion.
However, one can ask GitHub to install this service for repositories which are part of an organization. GitHub then configures an existing repository as such a mirror and pulls from it in an interval that is a function of the number of overall mirrors they have.
EDIT: as Stuart points out, GitHub no longer accepts requests for mirroring arbitrary repositories. The only remaining option is the solution I posted in my question, i.e., creating a post-receive hook to automatically push to your GitHub repository.
Judging by the current content of https://github.com/mirrors, it would appear GitHub no longer does "official mirrors", as most projects that want their code mirrored on GitHub today just makea an organization for it, such as Git itself.
There is also a feature request at: https://github.com/isaacs/github/issues/415
According to Importing a Git:
For purposes of demonstration, we'll use:
An external account named extuser
A GitHub personal user account named ghuser
A GitHub repository named repo.git
The command line:
# Makes a bare clone of the external repository in a local directory
$ git clone --bare https://githost.org/extuser/repo.git
# Pushes the mirror to the new GitHub repository
$ cd *repo.git*
$ git push --mirror https://github.com/ghuser/repo.git
# Remove the temporary local repository.
$ cd ..
$ rm -rf repo.git
I have used a tool called github-backup with moderate success to, if not mirror, at least make a full backup (including issues and other metadata) of a Github user or organization. To quote the README file:
Each time you run github-backup, it will find any new forks on GitHub. It will add remotes to your repository for the forks, using names like github_torvalds_subsurface. It will fetch from every fork.
It downloads metadata from each fork. This is stored into a branch named "github". Each fork gets a directory in there, like torvalds_subsurface. Inside the directory there will be some files, like torvalds_subsurface/watchers. There may be further directories, like for comments: torvalds_subsurface/comments/1.
You can follow the commits to the github branch to see what information changed on GitHub over time.
The format of the files in the github branch is currently Haskell serialized data types. This is plain text, and readable, if you squint.
Limitations include:
no private repository support
no "social" stuff like stars, followers, etc
notes to lines of commits are not supported (yet?)
issue labels