Git (or tortoisegit) marks LFS file as modified, prevents push or pull - tortoisegit

I'm having a problem with our git repo. We have one LFS file that is only ever modified by one of our users, on a mac. The mac user pulls and pushes without incident.
But on the Windows dev's PC, git (or tortoisegit) automatically marks the LFS file as modified, even when it's not. I think it's because the switch from pointer to file isn't cleanly understood by tortoisegit.
The ugly effect is that the Windows user tries to push and gets a "you must pull" message, but then tries to pull and gets a merge conflict due to the not-really-modified LFS file. However, there is no resolve... option in the tortoisegit dropdown for the supposed conflict. A revert sets the icon back to unmodified, but any tortoisegit action still fails as though the lfs file has been modified and resets the icon status to modified.
Since the user can't push, can't pull, and can't resolve a merge conflict that's causing the inability to push or pull, the user is stuck. I googled and found some old posts suggesting tortoisegit doesn't handle lfs quite right and causes this, but does anyone have any better idea of how to resolve this than scary trial-and-error with git commands?

A proper solution to this would be one in which the lfs file does not wrongly get marked as modified. However, I'm now using this workaround:
The (windows) user commits changes in tortoisegit, making sure to uncheck and thus not include the falsely-marked-modified lfs file in the commit
The user deletes (not tortoisegit deletes, just plain old windows file deletes) the falsely-marked-modified lfs file
The file is now shown as "missing" in tortoisegit status, if viewed
The user does a pull, and the lfs file is pulled successfully without a merge conflict
The user can now push the commit successfully
This is the method we are using until we discover a fix for the lfs file being incorrectly flagged as modified.

Related

Checked out a repo from remote but when I do a git status a file shows up as modified — how to fix?

I am using Windows and Git and I had modified a file. No matter how many times I did a git add and commit, the file kept showing up as modified and i could not for example do a git pull --rebase. I assume I did something wrong and screwed up the local Git repo so I decided to clone the repo from github, into a completely new directory. To my surprise, even in this new directory tree when I do a git status the same file shows up as modified -- it is as if it is somehow modified in the github (remote) repo which does not make sense to me. Moreover, the version of the file in cloned local repo does not have the latest version of the code that i can see when i look at the code on github. How can i fix this? I am concerned that someone else cloning the code will end up with the same problem. (Apparently only I am seeing this problem -- I did not somehow manage to corrupt the github repo which leads me to believe this is a git/windows issue.) As far as what I think I did wrong is when I modified a file and did a git add, i misspelled the directory path by using a lower case letter instead of an uppercase and then adding one file resulted in the other, properly spelled path showing up as modified and vice versa. I don't know if a symlink on windows got created -- the file contents are identical. But one would think cloning (via Eclipse) into a completely new directory tree would make this a non-issue.
I looked through replies but it seems like the basic problem is Window's case insensitivity and this caused some (to me) weird behavior. In particular, I simply could not delete one of the folders -- they were "entangled." So the simple solution was to delete the folder and its contents from unix which is case sensitive. Then I checked out a fresh repo and problems appear to be completely resolved.
You mentioned in a comment that you discovered one commit containing two problematic files: one named Login/Login.tsx and one named login/Login.tsx. This comment is on a related question; see my answer there for a discussion of Git's method of naming files in its index, vs what your OS requires in your working tree.
Your solution—use a Unix or Linux machine, where you get a case-sensitive file system, to repair the situation—is probably the easiest and best way to deal with this. If you can establish a case-sensitive file system on your own machine, that also allows easy dealing with this (see my answer to another related question for a macOS-specific way to make a case-sensitive file system).
Given that what you wanted was simply to delete one of the spellings, though, git rm should allow you do that. In particular git rm --cached login/Login.tsx would drop login/Login.tsx from Git's index, without affecting Login/Login.tsx. This could leave your working tree with an existing login folder, though.
It's important—at all times, really, but especially when working within a situation like this—to realize that Git itself doesn't actually need or use your working tree to make new commits. Each commit contains a full snapshot of every file that Git knows about. These files exist as "copies" in Git's index.1 Hence there are actually three copies of each file:
A frozen version of each file appears in the current commit (whatever that commit's hash ID is).
A "copy" (see footnote 1) of that version appears in Git's index. You can replace this copy with different content, and the read-only copy in the commit doesn't change. You can remove this copy entirely, and the read-only copy still doesn't change. Nothing in any existing commit can or will ever change. The index copy exists precisely so that you can replace it, or remove it, or whatever. In effect, the index—or staging area, if you prefer this term—acts as your proposed next commit. It's merely filled in from a commit.
Finally, there's a regular, ordinary, everyday file. This copy goes into your working tree or work-tree. To put this copy in place, Git must use your OS's file-manipulation facilities. That may require creating folders and files within the folders. If those are case-insensitive, and Git goes to create a Login folder when a login folder exists, or vice versa, the OS will say: nope, sorry, already exists. Git will do its best to accommodate the OS by using the "wrong" case anyway, and will create a file within that wrong-case folder—or perhaps destroy some other work-tree file that has the same name except for case, or whatever.
This last bit, where your work-tree files end up with the wrong names and/or in the wrong folders and/or end up overwriting similar files whose name differs in case somewhere, is a problem for you. It's not a problem for Git, though. Git just keeps using the index copies of each file. The next git commit you run uses whatever is in Git's index. The fact that your work-tree doesn't match is not a problem for Git. It's just a problem for you, because the normal everyday git add command means make the Git index entry for this file match the copy that's in my work-tree, and if that's the wrong copy, well, that's a problem.
In any case, once you have a correct commit in Git as your current commit, and extracted into Git's index, you can do whatever you like to your work-tree, including remove large swaths of it, or rename folders, or whatever. Get it set up however you like, then use git checkout or git restore to re-extract all or part of the current commit to your work-tree. Now that you've eliminated the name-case-issues in Git's commit and index, and cleaned up or removed any problematic files and/or folders in your work-tree, Git can create correct-case folders and/or files as needed. It's the process of getting the correct commit into Git that's painful, except on a case-sensitive file system.
1"Copies" is in quotes here because the files in Git's index—which Git also calls the staging area—are in a special Git-only format that de-duplicates content. When the copies that are in Git's index match the copies that are in some existing commit, Git is really just re-using the existing commit's files. Files with all-new content actually require a new internal blob object, which Git creates as needed; after that, the content will be de-duplicated as usual.

Exclude in git deleted important file

I have 2 branches master, testing. I git checkout testing and added an exclusion in .git/info/exclude
I added this into exclude: MyProject/MyProject.xcodeproj/project.pbxproj
I did this so it wouldnt prompt me to add it and commit it everytime because it changes whenever I change tab or stuff like that.
I committed this to testing and pushed, then I git checkout master and git merge testing.
In the terminal it said this: delete mode 100644 MyProject/MyProject.xcodeproj/project.pbxproj
And after this I cant open my xcode project anymore, it says cannot be opened because it is missing its project.pbxproj file
And now I cant seem to get it back, I cant find it in my github under commits. ;_;
Usually you put this stuff in your .gitignore rather than .git/info/exclude.
To get it back you could check out the commit right before removing it (assuming there is such a commit), move it someplace safe, and then re-add it after switching back to master.
If it's a file that is needed in the repository, then making git ignore it doesn't really make any sense (think of the guy cloning a fresh copy). Perhaps you'll have to live with either committing changes to it all the time, or get into the habit of leaving that file unstaged most of the time.

Files lost in Git repo download! Overwrote my work

I think I've done something rather stupid which may have cost me a couple of days of work. What follows is a question not so much about GIT itself as how to recover some files I have lost in the process of trying to use Git on a Mac.
I have been using Atlassian Sourcetree to make Git commits and pushes and to work with other members on a team. I have only been committing, pushing and pulling from Git.
As I've mentioned, I've been using SourceTree, but I wanted to evaluate Github for Mac as well.
At the time, I had made some changes to the files in my Git repo, representing about six hours of work. I did NOT commit or push these changes.
After I installed Github, I stupidly set Github to clone the repo to the same folder on my Mac as I had been making my changes in... essentially, Github downloaded the repo and overwrote all of my changes.
There were some files that were overwritten, and some new files that I created that were deleted.
Is there is a way to retrieve these files, either by some Git-based voodoo or some aspect of Mac OS X journaling that I'm not aware of? I would really appreciate hearing about it if there is.
So, from what I remember from having my life destroyed by my stupidity with git, it has a place where you can find your old code.
Go to your main repo folder and then type cd .git/lost-found/other/ or cd .git/lost-found/
You should be able to find a set of files that were older and you can then manually get them back by copying them in.
Here's some more links on it :
Recovering added file after doing git reset --hard HEAD^
Undo a git pull
http://www.quora.com/Git-revision-control/How-can-I-recover-a-file-I-deleted-in-my-local-repo-from-the-remote-repo-in-Git

Undoing a single-file Git Checkout

So, I am working on a project with XCode. Happily, I found out that it keeps an Git repository within every project. So, after a mistake on a code, i just used
git checkout aux.c
to move back from theses mistakes. Unfortunately, as i just found out, Xcode does not auto-commit, so, I ended up with a blank file.
I didn't commited anything after this, but still can't figure out how to undo this checkout.
Sorry, you can't. :-( You're going to have to replace the file some other way.
There are two places where git tracks your files - commits, and the index/staging area. Since there was no commit, and you checked the version of the file out of the staging area, there's no other place it would be.
Do run git status just in case, to make sure it doesn't still show staged changes to that file.
Any chance you had it open in an editor still and could undo the changes to the file that git checkout made? Some editors like Textmate and SublimeText will allow that; others don't.
If the file has never been committed to the repository then unfortunately you are out of luck.
From the sounds of it, you simply have an empty git repository, which will mean your file has been lost and something Versions (which comes with Lion) or Time Machine may be your best bet at recovering from your mistake.
To confirm if anything has been committed to the repository, use git log. If you get an empty response then you're out of luck on the git front.
Unfortunately, this probably this isn't the answer you were looking for.
In fact, undoing a first commit on git is impossible. So, if you are running Xcode, commit manually frequently.
But, there is another way.
If you are running OS X 10.7 Lion or latter (not sure about Snow Leopard), you can try to use the versions feature from OS X to recover any file. Too late for me, but it should work
Best way to recover if your uncommitted changes would be to go to (Left Pane) Source Control Navigator -> Stashed Changes -> Look for a file which dated/timed earlier than your commit which you would like to reverse and click to apply stash changes to the file. That would bring back all the unsaved files back.

How do you undo a hard reset in Git Gui or Gitk on Windows?

I'm using Git Gui and Gitk on Windows. How do I undo a hard reset from within the past two hours?
(Is it possible to do this from these applications, without using the command line?)
I saw this SO post, which says that undos are possible before git's garbage collection occurs. I might have quit and reopened one or both of these applications.
If you had changes in your working tree that were not committed when you did git reset --hard, those changes are gone for ever. You have to use your memory (in your head) to recreate them.
Changes that were committed after the commit to which you switched are not lost. They likely have no reference pointing to them, making them more difficult to locate. The tool to list all low-level changes to the repo is git reflog.
After you locate the commit which you want to revert to observe the hash number in the first row and use git reset --hard #hashnumber or git checkout #hashnumber to get the changes.
I found this useful line on http://quirkygba.blogspot.com/2008/11/recovering-history-with-git-reflog.html:
gitk --all $(git reflog | cut -c1-7)
This will display all the hidden changes in gitk, where you can comfortably view, point, click and create new branches.
As you mentioned the unreferenced commits are normally being kept in the repository for 30 days.
EDIT: I have to add stuff here so that my edit is at least 6 characters. I know, sometimes code fixes are less than 6 characters, but there might, after all, be something else to improve in this post.
See the answers by Brian Riehman and Pat Notz in the link in the question.
One solution is to use the command line.
In Windows, open DOS in the directory containing your .git directory.
Type something like the following to see what commit you want to go to:
"c:\Program Files\Git\bin\git.exe" reflog
To go to a certain commit, type something like the following, where the last expression is the SHA1 code of that commit:
"c:\Program Files\Git\bin\git.exe" reset --hard 5eb4080
I don't think you can undo a hard reset to get uncommitted changes back - you can undo a rebase because the blobs are still available, but if you never committed your newest changes to Git ever, anything it overwrote is most likely history. I'd love to find out that I'm wrong though!

Resources