343

I'm trying to make a local repo act as a remote with the name bak for another local repo on my PC, using the following:

git remote add /home/sas/dev/apps/smx/repo/bak/ontologybackend/.git bak

which gives this error:

fatal: '/home/sas/dev/apps/smx/repo/bak/ontologybackend/.git' is not a valid remote name

I'm trying to sync two local repos, with one configured as a remote named bak for the other, and then issuing git pull bak.

What is the best way to do it?

Daniel
  • 4,797
  • 2
  • 23
  • 30
opensas
  • 60,462
  • 79
  • 252
  • 386

4 Answers4

388

You have your arguments to the remote add command reversed:

git remote add <NAME> <PATH>

So:

git remote add bak /home/sas/dev/apps/smx/repo/bak/ontologybackend/.git

See git remote --help for more information.

Vincent Scheib
  • 17,142
  • 9
  • 61
  • 77
larsks
  • 277,717
  • 41
  • 399
  • 399
  • 12
    Is the `.git` at the end specifically required though? –  Sep 23 '16 at 10:47
  • 5
    It's just a path... Git doesn't care what it's named. – larsks Sep 23 '16 at 10:59
  • 2
    @ErikAigner traditionally, bare repos will end with a ".git" suffix. Though usually not as it's own directory, but rather as: "/path/to/projectname.git". - Other than than that it makes little difference. – Atli Apr 08 '17 at 09:10
  • 13
    It appears that you need to use an absolute path, which wasn't obvious to me. When I tried with a relative path, I got `fatal: '../dir' does not appear to be a git repository`. – Keith Layne Oct 30 '18 at 16:15
  • 9
    It's important to put `file://` on the front of the path and to use the full path to the local repository so that client software can access it through the expected protocol. And in answer to Erik's question above, the `.git` on the end of the path is apparently needed. – Scott Lahteine Jan 28 '20 at 10:11
  • 7
    At least in git 2.25+ (the version I have installed) you don't need to set the full path with the directory where the git metadata is (`.git`). So in the example is enough with `git remote add bak /home/sas/dev/apps/smx/repo/bak/ontologybackend` – Mariano Ruiz Jul 10 '20 at 15:57
  • However, the client needs write access to the local server folder. With true remote, it is easy done with the user@server remote url and user being the user with permission who created the server repo. – Timo Nov 01 '20 at 18:45
  • @KeithLayne As of time of writing (git v2.41.0), a relative path to a local git repo seems to work just fine. So either Git gained this feature (which is reasonably likely), or your issue was actually due to a mistake elsewhere. – cyqsimon Jul 12 '23 at 06:43
  • For windows use this pattern: git remote add bak file:///C:/dev/pokus/.git/ – Leos Literak Jul 27 '23 at 10:54
236

If your goal is to keep a local copy of the repository for easy backup or for sticking onto an external drive or sharing via cloud storage (Dropbox, etc) you may want to use a bare repository. This allows you to create a copy of the repository without a working directory, optimized for sharing.

For example:

$ git init --bare ~/repos/myproject.git
$ cd /path/to/existing/repo
$ git remote add origin ~/repos/myproject.git
$ git push origin master

Similarly you can clone as if this were a remote repo:

$ git clone ~/repos/myproject.git
Matt Sanders
  • 8,023
  • 3
  • 37
  • 49
  • 18
    This should be the accepted answer, because it perfectly fits the question "What's the best way to it?". The "local repo treated as a remote repo", as @opensas called it, is indeed a bare directory (just as a real remote repository) – Jack' Nov 23 '17 at 15:19
  • 2
    I suggest an edit : Whether you should use "git remot add.." + "git push" or just "git clone" is indicated here : https://stackoverflow.com/a/31590993/5446285 (adelphus' answer) – Jack' Nov 24 '17 at 08:49
  • 2
    @Jack - can you elaborate on what you found confusing? I'm happy to amend but want to keep the answer relatively succinct. – Matt Sanders Dec 05 '17 at 23:29
  • 1
    Note: A bare repository hides your files inside git blobs. To see them type: `git show $(git rev-parse HEAD):your_filename` – SurpriseDog Aug 01 '21 at 18:31
15

I am posting this answer to provide a script with explanations that covers three different scenarios of creating a local repo that has a local remote. You can run the entire script and it will create the test repos in your home folder (tested on windows git bash). The explanations are inside the script for easier saving to your personal notes, its very readable from, e.g. Visual Studio Code.

I would also like to thank Jack for linking to this answer where adelphus has good, detailed, hands on explanations on the topic.

This is my first post here so please advise what should be improved.

## SETUP LOCAL GIT REPO WITH A LOCAL REMOTE
# the main elements:
# - remote repo must be initialized with --bare parameter
# - local repo must be initialized
# - local repo must have at least one commit that properly initializes a branch(root of the commit tree)
# - local repo needs to have a remote
# - local repo branch must have an upstream branch on the remote

{ # the brackets are optional, they allow to copy paste into terminal and run entire thing without interruptions, run without them to see which cmd outputs what

cd ~
rm -rf ~/test_git_local_repo/

## Option A - clean slate - you have nothing yet

mkdir -p ~/test_git_local_repo/option_a ; cd ~/test_git_local_repo/option_a
git init --bare local_remote.git # first setup the local remote
git clone local_remote.git local_repo # creates a local repo in dir local_repo
cd ~/test_git_local_repo/option_a/local_repo
git remote -v show origin # see that git clone has configured the tracking
touch README.md ; git add . ; git commit -m "initial commit on master" # properly init master
git push origin master # now have a fully functional setup, -u not needed, git clone does this for you

# check all is set-up correctly
git pull # check you can pull
git branch -avv # see local branches and their respective remote upstream branches with the initial commit
git remote -v show origin # see all branches are set to pull and push to remote
git log --oneline --graph --decorate --all # see all commits and branches tips point to the same commits for both local and remote

## Option B - you already have a local git repo and you want to connect it to a local remote

mkdir -p ~/test_git_local_repo/option_b ; cd ~/test_git_local_repo/option_b
git init --bare local_remote.git # first setup the local remote

# simulate a pre-existing git local repo you want to connect with the local remote
mkdir local_repo ; cd local_repo
git init # if not yet a git repo
touch README.md ; git add . ; git commit -m "initial commit on master" # properly init master
git checkout -b develop ; touch fileB ; git add . ; git commit -m "add fileB on develop" # create develop and fake change

# connect with local remote
cd ~/test_git_local_repo/option_b/local_repo
git remote add origin ~/test_git_local_repo/option_b/local_remote.git
git remote -v show origin # at this point you can see that there is no the tracking configured (unlike with git clone), so you need to push with -u
git push -u origin master # -u to set upstream
git push -u origin develop # -u to set upstream; need to run this for every other branch you already have in the project

# check all is set-up correctly
git pull # check you can pull
git branch -avv # see local branch(es) and its remote upstream with the initial commit
git remote -v show origin # see all remote branches are set to pull and push to remote
git log --oneline --graph --decorate --all # see all commits and branches tips point to the same commits for both local and remote

## Option C - you already have a directory with some files and you want it to be a git repo with a local remote

mkdir -p ~/test_git_local_repo/option_c ; cd ~/test_git_local_repo/option_c
git init --bare local_remote.git # first setup the local remote

# simulate a pre-existing directory with some files
mkdir local_repo ; cd local_repo ; touch README.md fileB

# make a pre-existing directory a git repo and connect it with local remote
cd ~/test_git_local_repo/option_c/local_repo
git init
git add . ; git commit -m "inital commit on master" # properly init master
git remote add origin ~/test_git_local_repo/option_c/local_remote.git
git remote -v show origin # see there is no the tracking configured (unlike with git clone), so you need to push with -u
git push -u origin master # -u to set upstream

# check all is set-up correctly
git pull # check you can pull
git branch -avv # see local branch and its remote upstream with the initial commit
git remote -v show origin # see all remote branches are set to pull and push to remote
git log --oneline --graph --decorate --all # see all commits and branches tips point to the same commits for both local and remote
}

Jarek
  • 151
  • 1
  • 4
  • 6
    Welcome! and thanks for taking the time to put this together. Your willingness to get involved and give back to our community is the keystone of SO. – cb4 Feb 10 '21 at 19:08
  • yeah, being explicit is very helpful in this case. the ```git clone``` commands by themselves do some of these intermediate steps under the covers, it appears, and going through the pieces one by one helps in better understanding of the detailed mechanics. – dave campbell Oct 28 '21 at 16:55
5

It appears that your format is incorrect:

If you want to share a locally created repository, or you want to take contributions from someone elses repository - if you want to interact in any way with a new repository, it's generally easiest to add it as a remote. You do that by running git remote add [alias] [url]. That adds [url] under a local remote named [alias].

#example
$ git remote
$ git remote add github git@github.com:schacon/hw.git
$ git remote -v

http://gitref.org/remotes/#remote

Kristian
  • 21,204
  • 19
  • 101
  • 176