19

I have a git repo that is a fork of another repo. As a rule I will normally add a remote called upstream, which is the original repo I forked from.

$ git remote -v
origin git@github.com:skela/awesomeproject.git (fetch)
origin git@github.com:skela/awesomeproject.git (push)
upstream git://github.com/bob/awesomeproject.git (fetch)
upstream git://github.com/bob/awesomeproject.git (push)

Is there any way to have this additional remote persist across clones? Say I delete my local repository and do a:

git clone git@github.com:skela/awesomeproject.git

And now I recheck my remotes:

$ git remote -v
origin git@github.com:skela/awesomeproject.git (fetch)
origin git@github.com:skela/awesomeproject.git (push)

My upstream remote has vanished!

How to I ensure that my git repo always keeps these 2 remote aliases?

Edit: Just adding the main reason why I want to do this as to shape some of the answers down an acceptable path ;)

Goal is to have a branch in my repo that tracks the upstream's master.

[remote "upstream"]
    url = git://github.com/bob/awesomeproject.git
    fetch = +refs/heads/*:refs/remotes/upstream/*
[branch "father"]
    remote = upstream
    merge = refs/heads/master

In other words, the branch "father" which is in my repo tracks the remote called upstream's master branch.

It all works great once I set it up, but as soon as I clone the repo again, the "father" branch points to origin instead of the upstream.

Skela
  • 884
  • 10
  • 18
  • Possible duplicate of [Preserve git remotes](http://stackoverflow.com/questions/1572190/preserve-git-remotes) – sschuberth May 26 '16 at 12:09

3 Answers3

14

That is impossible. Git only clones the repo’s content, never its settings. If your want to hard-wire remotes into your repo (it stands to question whether that is a good idea), create a script repo-setup.sh in your repo root that does something like this:

git remote rm origin
git remote rm upstream
git remote add origin git@github.com:skela/awesomeproject.git
git remote add upstream git://github.com/bob/awesomeproject.git

Then run this file after you cloned the repository.

Chronial
  • 66,706
  • 14
  • 93
  • 99
  • 1
    submodule info gets across fine, so why shouldn't a remote? i'm not saying one should persist all remotes, but adding an upstream remote to a fork is such a common occurrence, surely there must be a proper git way to do it? – Skela Mar 08 '13 at 07:17
  • No, definitely not. Submodule info is also not completely cloned – only the `.gitmodules` file. The real remote for the submodules is stored in `.git/config`, which is also not cloned. – Chronial Mar 08 '13 at 08:03
  • with submodules, you only need to perform 2 git commands after a clone, so do you know if there is something similar with remotes? git remote init and git remote update dont seem to exist :P – Skela Mar 08 '13 at 08:10
  • have a look at GoZoner’s reply. Using this you need to run: `git clone`, `.gitremotes >> .git/config`. Or my suggestion needs: `git clone`, `./repo-setup.sh`. – Chronial Mar 08 '13 at 08:12
  • 1
    In case anyone else comes across this, I've gone with GoZoner's suggestion to copy the remote info I wanted. And also Chronial's suggestion in the comment above this. Essentially I end up having to do: git clone git@github.com:skela/awesomeproject.git , cat .gitremotes >> .git/config – Skela Mar 08 '13 at 08:23
  • I'm trying to use multiple remotes to keep several instances of a repo in sync with each other, with the idea being that any time committed changes get pushed, they automatically go to all repos. Yet this automatic stuff is broken if somebody has to (know and remember to) run a script in addition to every clone. Is there some better practice to accomplishing this? – Michael Jun 10 '17 at 18:12
  • @Michael it sounds like you could use git hooks inside of your remotes to handle that. – Chronial Jun 13 '17 at 14:52
5

Create a file .gitremotes that you populate with the content of .git/config related to remotes. Add .gitremotes to the repository. After the clone append .git/config with .gitremotes. Note: might need some hand editing if the remotes that you want to share (in .gitremotes) have a name conflict with the remote that 'git clone' creates automatically ('orgin').

To accomplish this easily you could define a bash function:

function git-clone-r ()
{
  src=$1
  tgt=$2
  git clone $src $tgt
  cat ${tgt}/.gitremotes >> ${tgt}/.git/config
}

[The above isn't all that sophisticated; but illustrates the point and works]

GoZoner
  • 67,920
  • 20
  • 95
  • 145
  • 2
    I use this scripts https://github.com/juanpabloaj/git-remote-init for save and recover the remote repos with the .gitremotes file – JuanPablo Jun 23 '13 at 21:15
  • @juanpablo nice script. I noticed that it assumes there are no remotes, and exits if there are any already defined. Do you typically bypass the default remote 'origin' that is set when you clone a repository? Otherwise this would of course exist after cloning and without doing anything special/non-standard, your script will return silently. Just curious about your workflow here. – timblaktu Oct 10 '20 at 20:10
1

This is a slightly modified version of GoZoner's solution.

You need to capture the info about all the remotes from your repo's .git/config into a file that you could store outside your git repository. You also need to take care of updating this file every time you add a new remote. This can in fact be added to your git repo, so that the next clone or pull brings in this file.

Starting with git 1.7.10+, git supports including external config files.

So you can add the following lines to your repo's .git/config to include the external config file containing the remote info:

[include]
    path            = /dir1/dir2/repo-remotes.gitinfo
Tuxdude
  • 47,485
  • 15
  • 109
  • 110
  • 1
    I can understand the reasoning behind keeping the file outside the repo, but I think that kind of invalidates what I'm trying to achieve here. In essence I want to add a branch that tracks this upstream remote, but the question gets way too complicated when I add that to the mix. – Skela Mar 08 '13 at 07:20
  • Tuxdude: Do you know if i for example add a .gitconfig or .gitremotes file to my repo, and then add [include] path=".gitconfig or .gitremotes" to the .git/config, will that persist across clones? – Skela Mar 08 '13 at 07:25
  • @Skela - in theory it should work. But after every clone, you need to at least update the include path to include this file. – Tuxdude Mar 08 '13 at 07:29
  • Ok thats, slightly better than GoZoner's solution, but still not ideal. I'm going to check git's release notes. Perhaps its added to a newer version? – Skela Mar 08 '13 at 07:32
  • Ok I don't understand this... i have two origins in .git/config, and the project is pushed to both origins, but when I clone from either, it *loses this* somehow! – Michael Jun 10 '17 at 18:05