-1

This seems like a duplicate question but all the answers I was able to find don't do what I need:

  • I cloned a single branch down (dev) using --single-branch.
  • Now I need to fetch the repo's main branch down with the clean main from remote and track the main branch from there.

Update with background:

  • I join a 5 year old repo with over 50+ branches. The main is in production and the others were branched out at some point in the past. Some were merged, some have been being merged to main, and some are just collecting dust.
  • The branch I'm working on shares some files with the main one but it's been modified several times and about 25 commits ahead of the main one with multiple files and subfolders that (I assume) should not be merged with main.
  • When I cloned the repo down, obviously I don't want to clone the whole 50+ branches that I'm not going to work on so I decided to clone only the branch that I need.
  • Now, I need to check with the main branch to make sure my code isn't going to conflict with it so I need a "clean" main from remote/GibHub that people've pushed code to.
  • I'd like to keep my code in my branch, clone just the main branch from GitHub with its code, and keep them separate.

I've tried:

  • git fetch <remote> <branch>:<local-branch> and it does the job but it carries the files of my local dev to the new main local branch and I don't want to do that because there are many changes currently in dev that I don't want to merge. I just want a clean main from remote.
  • git switch, git checkout, etc. as the answers I could find suggest but none of them works as expected.
Viet
  • 6,513
  • 12
  • 42
  • 74
  • 1
    "Carries the files of my local `dev` to the new `main`". It sounds like you just have files in your working directory that are untracked by `main`. They are not part of your `main` branch. `git status` should confirm that they are untracked. – chepner Jul 16 '21 at 13:40
  • 1
    If this is the case, you could move this files to some other directory, and they will be recreated when you do `git switch dev` again. – chepner Jul 16 '21 at 13:41
  • Thank you for your comment. Yes, I understand they're not tracked by main but also I don't want to see/have them in the local `main` because I'm going to make changes to the `main` before pushing it up. Is there away to remove them from my working directory? – Viet Jul 16 '21 at 13:46
  • Yes, just move them to another directory with `mv` or (if you are sure that checking out `dev` will restore them) just delete them with `rm`. – chepner Jul 16 '21 at 13:49
  • I could do that but there're many files in different subfolders. It's possible but I'd like to avoid that. Is there another way? – Viet Jul 16 '21 at 18:56
  • 1
    You can use `git clean` to remove untracked files. – Yoichi Nakayama Jul 18 '21 at 02:16

2 Answers2

2

You want to know what main looks like. Since you have a --single-branch clone consisting of just dev, you need to add main to the branches you want to fetch:

git remote set-branches --add origin main
get fetch

Now the remote-tracking branch origin/main is the current state of main. If your desire is to compare it with dev, you can just use

git diff dev origin/main

However, if you want to see main as actual files and directories, you would need to create a local version of origin/main, which you would probably call main:

git branch --track main origin/main

Okay, so now local main exists. But you still can't see the actual files and directories on your computer, directly, because you did not switch to (or checkout) the local main. The normal way to do that would be:

git switch main

If you do that, Git will balk and refuse to proceed if you have any outstanding uncommitted edits in the tracked files of dev. Assuming there are none, Git will change your working tree (the files and directories you can see): it will remove the tracked files of dev, and it will replace them with the files of main. That's usually okay, but if you have untracked files in the working tree, and main doesn't have a version of those files, they will remain in place during the switch, and you would not be seeing in the working tree a correct representation of what origin/main looks like now.

It appears from your question that you don't like that.

So what can you do? Well, one possibility would be to stash your untracked files before doing the switch. But there's another possibility: you could use the git worktree command to check out main into a different working tree folder. That way, you can manually inspect your working tree, with dev checked out and all your untracked / edited files still in place, and the other working tree, with main checked out, at the same time in two different directories.

matt
  • 515,959
  • 87
  • 875
  • 1,141
1

Git is not about files. Git is about commits.

The --single-branch option limits the set of remote-tracking names that your Git stores. This may, or may not, reduce the number of commits obtained. It has nothing to do with the number of branch names you can create and use locally (which makes it kind of the wrong name, but I have no suggestions for a better name: --single-remote-tracking-name might be slightly better, but is annoyingly verbose).

Now I need to fetch the repo's main branch down with the clean main from remote and track the main branch from there.

I cannot make heads or tails of the phrase with the clean main from remote, but I can once again point out that Git is all about commits. Every commit is fully, totally, completely read-only. If some remote Git repository has commit a123456, and you have commit a123456, you and they have the same commit. The contents of commit a123456 in your Git repository exactly matches the content of commit a123456 from that other Git repository, by definition. The commit's hash ID is the commit, and you either have that commit, or you don't have that commit. That's all there is to it: there's nothing "clean" or "dirty" about it.

If you insist on using --single-branch when running git clone, you can repair the single-branch-ness after the fact: see How do I "undo" a --single-branch clone? If you like, you can use git remote set-branches --add to add one or more names to the set of remote-tracking names; see the same question, referring specifically to Arno Fiva's answer.

Remember, Git is about commits. If you have the commit, you have the commit. If not, git fetch will get the commit, provided that the other Git has it and you're using a full, non-shallow clone. If you're using single-branch and/or shallow clones, you may need to widen the number of remote-tracking names you use and/or deepen your clone until you get the commit.

To get the files out of the commit, you need a separate step, such as using git checkout, git worktree add, git archive, or similar. Which of these to use (if any) depends on what you're really trying to do, and as I noted earlier, I do not understand what you are trying to do.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thanks for your answer. I've updated my question to clarify. – Viet Jul 18 '21 at 12:29
  • 1
    @Viet: looks like matt supplied the answer you wanted, which is similar to the one I linked above from Arno Fiva. I'll note that the carrying costs for a full clone (including the gathering-dust-branches) is *usually* quite small, but any one repository could be quirky: some branch in their Git repository might include a commit that holds 50 GB of DVD images, perhaps. :-) But usually `--single-branch` is not worth the price you pay in extra inconvenience. – torek Jul 19 '21 at 01:52
  • Thank you @torek. I'll keep that in mind. – Viet Jul 19 '21 at 13:03