1

Here's my situation: (This is typical of how I personally like to work with code)


I create a directory on my filesystem somewhere, cd into it, and start creating and editing some code files.

If the project starts taking a productive trajectory, I will at some point decide that it is useful to initialize some version control and to have a backup. So I will create a git repository, add all files to it, set the "origin / master" thing and then do a push.

So now I have a GIT repo on a server somewhere which I created from a directory on my system.


Then, some time later, I will have some idea for something I want to try. I could use branches for this, but this is usually inconvenient. Instead I will copy the entire directory, and then edit code in the new directory.

So now I have another directory. It contains a copy of the git repo, so "it thinks" it is the same as the original directory. Git doesn't know I've copied the directory somewhere else.

What I want to do is to keep the history of this repository, but create a new "origin master" on another server somewhere, and change the name of the repository to match the name of the directory which contains it. (Directory has a different name to the original directory it was copied from.)


I assume this must be fairly trivial to do, but I've never seen any description of how to do it in any tutorials and searching for "copy directory change git repository" obviously doesn't return a lot of useful info.

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • 1
    Does this answer your question? [How to change the URI (URL) for a remote Git repository?](https://stackoverflow.com/questions/2432764/how-to-change-the-uri-url-for-a-remote-git-repository) – mkrieger1 Feb 06 '21 at 10:52
  • @mkrieger1 No it doesn't, because I don't have another repository on the server side which already exists. Presumably to create one is part of the answer. – FreelanceConsultant Feb 06 '21 at 10:56
  • 1
    Yes I thought that was implied. – mkrieger1 Feb 06 '21 at 10:56
  • I presume creating an empty repo server side and then changing the URI will not work, because the server side repo will have "unrelated history" – FreelanceConsultant Feb 06 '21 at 10:58
  • Read the [Git book](https://git-scm.com/book/en/v2). It is a very good start. – axiac Feb 06 '21 at 10:58
  • @mkrieger1 My guess would be the solution is to change the URI of the new copy repo, and then somehow push this to the server, despite the fact that it doesn't exist on the server. I have no idea how to do this. – FreelanceConsultant Feb 06 '21 at 10:59
  • @axiac Which Chapter/Section – FreelanceConsultant Feb 06 '21 at 10:59
  • See also https://stackoverflow.com/questions/9844082/how-to-create-a-new-git-repository-from-an-existing-one and https://stackoverflow.com/questions/6648995/how-to-create-a-remote-git-repository-from-a-local-one – mkrieger1 Feb 06 '21 at 11:05
  • @axiac Having scanned breifly through the git book I am fairly sure this isn't covered. – FreelanceConsultant Feb 06 '21 at 11:10
  • The basic Git concepts are covered in the book. You don't need a set of commands to copy-paste, run and forget. You need to understand how Git works. Otherwise you'll come tomorrow with a similar question (or the same question). – axiac Feb 06 '21 at 11:29
  • @axiac In this case the solution was a manual change of URI and then a standard push. Not something that is easily guessable from the limited cases covered in the book. Again if you have a page number where this is covered then your point will be proven, otherwise this conversation is pointless. – FreelanceConsultant Feb 06 '21 at 12:01

3 Answers3

2

You may be surprised to learn that this is actually something git's model explicitly supports. Although it's commonly used with a central "canonical" repository, the design of git is completely decentralised, and every clone of a repository is equal.

When you copy the directory containing a git repository you are, in git's terms, creating a fork of that repository. You can even use the git clone command to do the copying, and it will do some clever tricks to save disk space. There is no "name" for a repository, just a location.

The only part that will seem like it's "linked" to the old repository is the meaning of "origin", which git terms a "remote". In common usage, you might have lots of people with working clones all with the same remote, called "origin", and pointing at a clone somewhere like GitHub; but you can have any number of remotes, pointing at any git repository you like - it doesn't even have to share any history with the local one!

All this is background to understand why your solution is this simple:

git remote set-url origin someuser@someserver:somepath

You're simply saying "from now on, when I say 'origin' in this clone, I mean this repository".

Of course, you first need to know that URL, which means creating the repository on the remote server somehow. For a service like GitHub, this is the same flow as if you had created a private repository and wanted to make it available on GitHub. When you create a repository on these services, you can opt for it to start completely empty, without even an initial commit, and it will tell you the URL to point your "origin" remote to.

Then you just use git push to populate it with one or more branches from whatever repository you want. You can also use gut push --mirror to push all your local branches at once.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • I'm aware of all this information. The question is, after copying the directory, how do I change which repo the "remote" is, if another remote does not exist yet? My assumption would be there is some way to do a special kind of "push" action which creates a new repository on a specified server with a specified repository name. But this is a pure guess. – FreelanceConsultant Feb 06 '21 at 11:12
  • @user3728501 No, you create the repository first, you just create it completely empty. See my added paragraph. – IMSoP Feb 06 '21 at 11:13
  • Right ok, so create a blank project on GitLab, then push to this after changing the `set-url`? – FreelanceConsultant Feb 06 '21 at 11:15
  • There is no special way. You initialize a new empty repo on GitHub (make sure not to add a Readme.md and git Ignore as part of initialization), you can then push your local repo into it. If you did initialize the repo with a Readme, you can force-push to ignore the remote history once. – jessehouwing Feb 06 '21 at 11:16
  • Presumably you meant `git@github.com:username/repo` and not `git@github.com/username/repo` by the way? – FreelanceConsultant Feb 06 '21 at 11:19
  • 1
    Depending on the Git hosting service you use, there may be a CLI to initialize the remote repo from your local machine, eg for GitHub use `gh repo create`: https://cli.github.com/manual/gh_repo_create – jessehouwing Feb 06 '21 at 11:19
  • I also had to manually edit the git config file to add `.git` to the end of the origin URI. This matches with what I have in the other `.git/config` files on my system which are related to the same server. – FreelanceConsultant Feb 06 '21 at 11:20
  • 1
    @user3728501 Yes, the example URL was typed by hand; use whatever URL your hosting service tells you to use when you've created the repository. – IMSoP Feb 06 '21 at 11:23
  • @user3728501 Editing the git config file is just the same as running the command I gave, you just gave it slightly the wrong URL. I've edited the example to look less real, so any future reader doesn't try to copy and paste it. – IMSoP Feb 06 '21 at 11:28
2

The command your looking for is: git remote set-url <remote_name> <remote_url>. For your preferred workflow it should work as follows:

Create a new working directory:

mkdir <working_directory>

Clone your actual repository into the new working repository:

git clone <path_or_url_of_old_repository> <path_or_url_to_working_directory>

Do some development in your working directory. If you reach the point, were you decide, that you need a new remote repository, create a new folder for it and initialize it:

mkdir <new_remote_repository>
cd <new_remote_repository>
git init

If you're working with local repositories switch to some development branch to avoid git push errors:

git checkout -b <name_of_development_branch>

Next switch back into your working directory and change the orgin url to the newly created repository:

cd <working_directory>
git remote set-url origin <new_remote_repository>

And push your actual work into the new remote repository. Doing it this way, the complete history is kept.

AnPla
  • 32
  • 1
  • 5
  • A couple of points that might be worth adding: 1) For most people, the remote repository is not on a server they have shell access to, it's on a service like GitHub or GitLab. So the steps involving `mkdir` and `git init` will generally be via the web interface or proprietary API of those services. 2) If you _are_ running your own central git server, you will generally want `git init --bare`, so that there is no working copy on the server. – IMSoP Feb 06 '21 at 18:19
  • I'm absolute with you, for normal workflows. But the workflow of user3728501 is some kind of personal. And as I understood user3728501 explicit does not use a bare repository, but works sometimes directly in the origin repository. – AnPla Feb 07 '21 at 08:14
  • Well, in comments elsewhere they mention GitLab, but your right the question does say the remote would be "on another server somewhere". I didn't interpret that as meaning another server with a working copy, though. – IMSoP Feb 07 '21 at 10:46
1

Here's my situation: (This is typical of how I personally like to work with code)

What I write below is not a real answer to your problem but, as I find your workflow inefficient, I want to give you new ideas to perhaps improve it.

I create a directory on my filesystem somewhere, cd into it, and start creating and editing some code files.

If the project starts taking a productive trajectory, I will at some point decide that it is useful to initialize some version control and to have a backup. So I will create a git repository, add all files to it, set the "origin / master" thing and then do a push.

Create a git repository from the beginning. A lot of people underestimate how the use of a local repository could help your during your development. Commit every time you have a new step working or when you want to try a solution you don't know if it will be the good one. Git will allow you to revert your changes easily or compare file, see changes,...

So now I have a GIT repo on a server somewhere which I created from a directory on my system.

Then, some time later, I will have some idea for something I want to try. I could use branches for this, but this is usually inconvenient. Instead I will copy the entire directory, and then edit code in the new directory.

Here is the real improvement on your workflow. I could imagine that you don't know git worktree.

It allows you to work with another branch in another working directory.

With the command:

git worktree add -b new-idea ../NewIdea master

you will create a new branch new-idea starting from master (for example) and checked out it in the working directory NewIdea.

That way you could work in NewIdea folder.

Advantages:

  • You only have one repository that track all the branches histories. No need to create a new repository on the server and update the remote url to still be able to commit and push
  • You keep the relation between all the folders/histories and are able to compare changes, cherry-pick commits,...
  • You have only one repository that keep all the history, so if your repository is big, you save some space.
Philippe
  • 28,207
  • 6
  • 54
  • 78
  • The point of what I'm doing is to avoid the complexities of using git. It's a bit like avoiding diamond inheritance. I don't want to work with a repository with many branches, and therefore forget what each one does. If the tool doesn't make life easier and more convenient, but more arduous and difficult, then don't use it. I could use a JCB digger with a knife welded to the bucket to open my mail, and sure enough this would impress a lot of people, but at the end of the day my neighbour "Big Rob" opens his mail the "boring" way and he thinks I'm an idiot for using a JCB. – FreelanceConsultant Feb 06 '21 at 12:06
  • @user3728501 The complexity to manage multiple repo with 1 branch or 1 repo with multiple branches is the same (for what you do). If you find that the only command I gave you is too complicate, I tend to think that you have to spend some time to learn your tools. That make me think to that: https://hakanforss.files.wordpress.com/2014/03/are-you-too-busy-to-improve2.png – Philippe Feb 06 '21 at 12:30
  • No, it is not the same. Working with different directories simultaniously is useful for the work I am doing. Maintaining multiple branches of a single repo is not useful. – FreelanceConsultant Feb 06 '21 at 13:00
  • 1
    @user3728501 your answer make me think that you didn't had a look at what is a git worktree that let you have multiple directories where to work simultaneously for a same repository. (So you down vote without understanding the answer?). Being able to create as many directories you want and being able to push without having to create a remote repository every time and change the remote url (with the bonus to keep the histories related so that it could help you later) is for me much more simpler. – Philippe Feb 06 '21 at 14:15
  • It's simply a case that I neither want nor need to use git for such a simple purpose. Its just not the appropriate tool for the job – FreelanceConsultant Feb 06 '21 at 14:30