15

Is there a git statement that has the same result as a fresh git clone?

So even if there are extra branches, extra files, other files, local tags anything... which command can accomplish this?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
byenary
  • 301
  • 2
  • 3
  • 7
  • 4
    There's a git clone command.... – Mad Physicist Oct 25 '18 at 18:06
  • 1
    Hi, and welcome to StackOverflow. What is the reason you want to do this? I ask because if you've gotten your repository into a bad state there's usually a better way to fix it than wiping everything out. – Schwern Oct 25 '18 at 18:26
  • Ok removing the directory, looking vor the correct url...and then git clone works but it would be convinient to do this without removing and recloning.. – byenary Oct 25 '18 at 18:26
  • @schwern : sometimes some work was done, some things committed some not etc.. then dont't work on a project for weeks, other people keep working.. when you then come back to a project you want to start clean without figuring out where your local code is compared to the remote – byenary Oct 25 '18 at 18:29
  • 2
    @byenary Oh, there's much better ways to bring your repo up to date. `git pull` is the primary mechanism. – Schwern Oct 25 '18 at 18:33
  • @Schwerm, I know but this can still leave me with a lot of unnecessary branches, tags and stuff which can be confusing. – byenary Oct 25 '18 at 18:45

3 Answers3

12

Your best option to remove all local artifacts is to make a fresh clone.

Otherwise, you have to run different commands to perform the individual components of the cleanup.

To get rid of all untracked files, use git clean, with any number of flags turned on to wipe out everything:

git clean -fd

Now reset all your branches to the remote version (git reset) or delete them if they are local-only (git branch):

git checkout master
git reset --hard origin/master

git branch -d local-branch

The same goes for tags. You can delete all local tags like this:

git tag -d $(git tag -l)

You can do a lot of these operations manually as well, by manipulating the contents of the .git folder, if you know what you are doing.

As you can see, git clone is by far the easier option.

silviot
  • 4,615
  • 5
  • 38
  • 51
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • Okay yeah I was afraid this was the case but maybe there was some secret single git command way :-) Ok so rm -Rfv & git clone is the way :-) – byenary Oct 25 '18 at 18:37
  • this answer makes some assumptions ... the upstream you want to track is `origin` ( which granted is often true), and the default branch or the branch you care about is `master` ( less often true ) – erik258 Oct 25 '18 at 18:44
  • 1
    @Dan Those are examples, not assumptions. The assumption is that OP will use this code with understanding, instead of literally. I assumed that they (and future readers) read carefully enough to understand that `origin` is an example of ``, and `master` is a sample stand-in for ``. I appreciate you making it explicit though. – Mad Physicist Oct 25 '18 at 18:47
5

If you really want to delete all local work I also think cloning the simplest thing. If the repository is big and/or the network is slow then you can use these options:

git clone --reference existing-clone --dissociate URL new-clone
silviot
  • 4,615
  • 5
  • 38
  • 51
A.H.
  • 63,967
  • 15
  • 92
  • 126
2

sometimes some work was done, some things committed some not etc.. then dont't work on a project for weeks, other people keep working.. when you then come back to a project you want to start clean without figuring out where your local code is compared to the remote

If all you want is to bring your local branches up to date, you can solve this without wiping out your repository. Let's say your repository looks like this.

          D - F [feature]
         /
A - B - C [origin/master]
         \
          G - H [master]

You can get a very similar view with git log --graph --decorate --all, though it will be sideways.

You made some changes to both master and a new branch called feature. You already have clean versions of the remote work. origin/master tracks the remote work on the remote master branch.

This doesn't stay up to date automatically. You can update it, and all your other remote tracking branches, with git fetch -p (-p will prune any old remote branches).

git fetch -p

          D - F [feature]
         /
A - B - C - I - J - K [origin/master]
         \
          G - H [master]

Now that your origin/master is up to date you can look at it like any other branch to see the latest work.

You can bring any other local branch up to date with the latest changes with git rebase origin/master. This will replay any local changes on top of origin/master. For example, to update the feature branch...

git checkout feature
git rebase origin/master

                      D1 - F1 [feature]
                     /
A - B - C - I - J - K [origin/master]
         \
          G - H [master]

Or, if you're not interested in a branch anymore, you can delete it.

git branch -D feature

A - B - C - I - J - K [origin/master]
         \
          G - H [master]

Finally if you simply want to throw out your changes on master use git reset --hard to force master to move to origin/master.

git checkout master
git reset --hard origin/master

                      D1 - F1 [feature]
                     /
A - B - C - I - J - K [origin/master]
                      [master]

And now you're up to date.


To answer the question about wiping out a repository...

Git repositories are generally very small (if they aren't that will cause other issues). Assuming you have decent network connection the simplest thing to assure a truly clean reset is to clone it again.

If that's not possible, the next best option is to follow these instructions. But getting out of a jam by cloning a new repository is a bad habit to get into. Practice gardening your repository.

clone your existing clone and clear out its local branches and tags. This will guarantee things like .git/hooks and .git/config are reset.

First, clone the local dirty repository.

git clone /path/to/the/dirty/repo /path/to/the/new/new_repo
cd /path/to/the/new/new_repo

Then delete all your local branches and tags.

Git won't let you delete the current branch, so checkout origin/master, the upstream version of master.

git checkout origin/master

Get all your local branches and delete them.

git for-each-ref --format '%(refname:short)' refs/heads

Get all your local tags and delete them.

git for-each-ref --format '%(refname:short)' refs/tags | xargs git tag -d

Recreate a fresh local master from origin/master and check it out.

git checkout -b master origin/master

Set your origin to be the original repository. You can get that from git remote -v in the dirty repository.

git remote set-url origin <original origin url>

Finally do a git pull to get the latest version of the upstream repository, its branches, and update master.

git pull

As you can see, it's easier to garden an existing clone.

Schwern
  • 153,029
  • 25
  • 195
  • 336