3

I cloned a project that I'm working on. Then I'm trying to move to a specific branch using git checkout branch_name and nothing happens, the terminal just add a blank line. After awhile the terminal is in the same state. Nothing changes.

I cloned it using git lfs clone https_url_to_repo

What I tried:

  • Clone it again
  • Reinstall git in my mac

Nothing worked.

Git version = 2.13.2 (installed using homebrew)
Git-lfs version = 1.5.5 (installed using homebrew)

Note: I can move to other branches, the issue is just with that one. Maybe the issue was caused because there was an interruption in my internet connection while moving to that branch.

Matusalem Marques
  • 2,399
  • 2
  • 18
  • 28
Gabriel Goncalves
  • 5,132
  • 3
  • 25
  • 34
  • 1
    Does the branch exist ? – Zooly Jul 04 '17 at 22:33
  • yes it is in the remote repo. A coworker can access it in his mac. Maybe the issue was caused because I had an internet interruption while moving to that branch @Zooly – Gabriel Goncalves Jul 04 '17 at 22:37
  • 1
    How? Moving to branch is a completely local operation. It has nothing to do with network connection. – 0andriy Jul 04 '17 at 22:39
  • Post the output of `git branch -a --list \*branch_name`. – 0andriy Jul 04 '17 at 22:39
  • @0andriy when you move to remote branch I guess it need network connection – Gabriel Goncalves Jul 04 '17 at 22:43
  • Instead of guessing better to read some documentation, right? – 0andriy Jul 04 '17 at 22:44
  • This is what I get @0andriy `remotes/origin/branch_name` (red color) – Gabriel Goncalves Jul 04 '17 at 22:46
  • `git pull origin branch_name` ? – Zooly Jul 04 '17 at 22:46
  • `git checkout origin/branch_name`(no copy, anonymous branch) or `git checkout -b origin/branch_name`(with copy). Before doing that ensure you have no other Git operation in progress. – 0andriy Jul 04 '17 at 22:48
  • same issue with that. I tried those two already @0andriy Do you know if there is a way to force to print the error or check a log to see what is happening? – Gabriel Goncalves Jul 04 '17 at 22:51
  • Do `git reset --hard HEAD~0` followed by the above. Update your post with the commands how you cloned it. – 0andriy Jul 04 '17 at 22:51
  • updated @0andriy – Gabriel Goncalves Jul 04 '17 at 22:57
  • 1
    The "LFS" part is very important! A regular Git repository is self-contained, but LFS repositories are different: instead of storing large files, they store only a *reference* to the large file. This means that checking out a commit that has a large file requires that your machine load that file over the network. (I added the git-lfs tag.) – torek Jul 04 '17 at 23:41
  • thanks @torek so, maybe it's that causing the issue? – Gabriel Goncalves Jul 05 '17 at 13:59
  • Maybe so; I have no experience with git lfs so am not sure what happens at the point of `git checkout`. I did find this: https://github.com/git-lfs/git-lfs/issues/1880 – torek Jul 05 '17 at 14:13
  • thanks @torek I noticed I have git-lfs version = 1.5.5 I'm going to update it and try again. Let's see – Gabriel Goncalves Jul 05 '17 at 14:20
  • 1
    In fact, after reading the description there and in the linked patch to git-LFS, that's *so* likely to be the problem, that I will go ahead and post it as the answer. – torek Jul 05 '17 at 14:21

1 Answers1

2

Summary:

This is most likely due to a buglet in Git-LFS, the fix (or at least workaround) for which is in a slightly newer version of Git-LFS.

See https://github.com/git-lfs/git-lfs/issues/1880 and https://github.com/git-lfs/git-lfs/pull/1932 for a a description of the bug and fix/work-around.

Here's my capsule summary though:

When you use Git-LFS, your standard Git configuration is modified to use Git's clean and smudge filtering processes. A smudge filter is meant to "dirty up" a file as it comes out of the version control system, and a clean filter is its logical opposite: it cleans up the file for storage inside the VCS. To use such filters, you must mark up both your .git/config file and your .gitattributes file; Git-LFS does this marking-up for you automatically.

As a somewhat silly example, some people like to have each line end with CR-LF instead of just a newline (LF-only), yet store the version-controlled version of the file with newline endings. Git can do this directly (using end-of-line filters) but if for some reason you wanted to write a program to do it yourself, you would use the smudge filter to replace LF-only with CR-LF, and use the clean filter to replace CR-LF with LF-only. Your work-tree files would then have your desired Windows-style line endings, while your committed files would have the desired Linux-style line endings.

More practically, some people like to expand keywords (RCS- or CVS-like $Id$ for instance). Git also includes a built-in ident filter that does this specifically for $Id$. The expansion is done when extracting files to the work-tree (as if by a smudge filter), and removed—put back to just $Id$—when adding files to go into new commits.1 If you wanted to handle more keywords, e.g., $Log$,2 you would have to write your own filters.

What Git-LFS does is to use (abuse?) the clean and smudge filters to replace large files with specially decorated hash IDs that act as "pointers" to external large-file storage. This way, Git never stores—or even sees, in a sense—the large files at all. It sees, and stores, only these decorated hashes. The Git-LFS filters are responsible for replacing a funny hash with the actual large-file contents on checkout, and replacing the large-file contents with a funny hash (new or re-used as appropriate) at git add time.

But there is a technical glitch: Git uses pipes to implement both smudge and clean filters. (These pipes have become quite fancy recently; see the Long Running Filter Process section of the gitattributes documentation.) The Git-LFS code and the Git code itself must be careful not to "constipate" the pipes ... and, well, it wasn't. (See my answer to live output from subprocess command for some of the details.)


1Specifically, smudge filters (along with ident and any end-of-line hacking) are applied to files when they are copied from Git's index to the work-tree. Clean filters are applied to files when they are copied from work-tree into the index. Since committed trees are built only from files as found in the index, and the index version is always "clean", all commits are always clean as well.

2What $Log$ does in RCS and CVS is to expand to the entire log-message history of the file—essentially, all the commits that touched the file, except that RCS and CVS are file-based rather than commit-based—so that the history is there while you are editing the file itself. Having actually used such things before, I am firmly convinced that this is a bad idea: this kind of metadata belongs only in the version control system (which, like Git or Mercurial, should be distributed with developers given access to the entire repository). Nonetheless, there are people who like this, and it is technically possible to do it in Git.

Gabriel Goncalves
  • 5,132
  • 3
  • 25
  • 34
torek
  • 448,244
  • 59
  • 642
  • 775