121

I have a directory gitrepo1. This directory is a git repository.

  • I would like to move this gitrepo1 into another directory newrepo.

  • Directory newrepo should be the new git repository with no loss of git history and should contain the directory gitrepo1.

  • Directory gitrepo1 should just be a directory now (inside newrepo), without any .git index, i.e. it should NO longer be an independent git repository or a submodule.

How can I do this?

NickD
  • 4,598
  • 1
  • 17
  • 33
Pranjal Mittal
  • 8,544
  • 14
  • 63
  • 91

4 Answers4

127

It's very simple. Git doesn't care about what's the name of its directory. It only cares what's inside. So you can simply do:

# copy the directory into newrepo dir that exists already (else create it)
$ cp -r gitrepo1 newrepo

# remove .git from old repo to delete all history and anything git from it
$ rm -rf gitrepo1/.git

Note that the copy is quite expensive if the repository is large and with a long history. You can avoid it easily too:

# move the directory instead
$ mv gitrepo1 newrepo

# make a copy of the latest version
# Either:
$ mkdir gitrepo1; cp -r newrepo/* gitrepo1/  # doesn't copy .gitignore (and other hidden files)

# Or:
$ git clone --depth 1 newrepo gitrepo1; rm -rf gitrepo1/.git

# Or (look further here: http://stackoverflow.com/q/1209999/912144)
$ git archive --format=tar --remote=<repository URL> HEAD | tar xf -

Once you create newrepo, the destination to put gitrepo1 could be anywhere, even inside newrepo if you want it. It doesn't change the procedure, just the path you are writing gitrepo1 back.

Robert Harvey
  • 168,684
  • 43
  • 314
  • 475
Shahbaz
  • 42,684
  • 17
  • 103
  • 166
  • 6
    +1. It's probably worth mentioning [this gotcha](http://stackoverflow.com/a/17747571/761202) affecting repositories created with git version 1.7.8 or 1.7.9 - which can mean moving a git repo makes it unusable (though as indicated it's easily corrected). – AD7six Sep 30 '13 at 14:56
  • 1
    i am on wndows machine and using command prompt. i couldn't find "cp" command. is "cp" command specific to other OS? – LP13 Dec 11 '15 at 17:27
  • 3
    @user3862378, `cp`, like almost every command or function is specific to other OSes. In fact, it's specific to every OS that is not windows. Try calling microsoft and asking them why they aren't POSIX. Anyway, `cp` means copy. `mv` means move. `rm` means remove. You can find windows equivalents. – Shahbaz Dec 13 '15 at 15:39
  • @Shahbaz Thanks, the solution above creates the following structure "newrepo->.git" and "newrepo->all other files from gitrepo1"...its not putting "gitrepo1" folder inside "newrepo"..i'm curious if creating folders manually in windows and moving ".git" folder under the root folder..would work without affecting the history? – LP13 Dec 14 '15 at 18:29
  • 2
    @user3862378, there is no reason why it shouldn't. `.git/` contains all of the history, which includes your latest commit. Wherever you put it, you have all the history. In fact, if all the files in that directory are different from the original repo where you took `.git/` from, the only thing would be that it tells you some files are deleted and some untracked ones are present. With a `git reset --hard`, the removed files would be recovered automatically! Only thing to note is that just by copying `.git/` you cannot recover the uncommitted changes. – Shahbaz Dec 15 '15 at 14:19
  • But wait I mean wouldn't this all mean that the history in `gitrepo1` gets deleted? I thought the asker wanted no loss of git history. I understood the question as "how do I merge the git history in one repo with another", which is also what I would want to know. Is that even possible? – Marses Oct 01 '20 at 07:21
  • No op says the original directory should be without history. See question. If you want to merge two repos, you can actually do that with git itself, but if they are unrelated repos, I don't see much benefit in that. Feel free to ask a new question for that, but the short answer is to do this in one of the repos: `git remote add other_repo path/to/other/repo; git fetch other_repo`. – Shahbaz Oct 02 '20 at 19:57
8

It's even simpler than that. Just did this (on Windows, but it should work on other OS):

  1. Create newrepo.
  2. Move gitrepo1 into newrepo.
  3. Move .git from gitrepo1 to newrepo (up one level).
  4. Commit changes (fix tracking as required).

Git just sees you added a directory and renamed a bunch of files. No biggie.

david.pfx
  • 9,271
  • 2
  • 19
  • 54
5

To do this without any headache:

  1. Check out what's the current branch in the gitrepo1 with git status, let's say branch "development".
  2. Change directory to the newrepo, then git clone the project from repository.
  3. Switch branch in newrepo to the previous one: git checkout development.
  4. Syncronize newrepo with the older one, gitrepo1 using rsync, excluding .git folder: rsync -azv --exclude '.git' gitrepo1 newrepo/gitrepo1. You don't have to do this with rsync of course, but it does it so smooth.

The benefit of this approach: you are good to continue exactly where you left off: your older branch, unstaged changes, etc.

emremrah
  • 1,103
  • 8
  • 15
5

I am no expert, but I copy the .git folder to a new folder, then invoke: git reset --hard

Community
  • 1
  • 1