How to re-download whole repository in Git - windows

We are team of users, who work on Windows, our Remote is in Bitbucket (Linux/UNIX) and our application is being deployed to Linux machine. We didn't pay attention to line endings, until one day we found out, that .sh scripts on our laptops have CRLF line endings. We decided to set core.autocrlf to false, so there will be no differences between line endings on Remote and line endings on our Windows laptops. However, this option does not change CRLF in our local source code.
Is there any way, how to tell Git to update all files so CRLF will be changed to LF as it is on Remote? Some kind of re-download, that would download even unchanged files.

No, there is no way to tell git to change all your files for you. Git simply stores the files. But you can clone your repo, update your files locally, and then push the changes back.
From a unix-style shell you could use the commonly available tool dos2unix for easy conversions. Something like this might fly:
git clone bitbucket:path/to/repo foo
cd foo
find . -type f -name \*.sh -exec dos2unix {} {} \;
git add .
git commit -m 'convert line endings on .sh files'
git push
If you can't find dos2unix, you can duplicate the functionality with a number of other tools, for which answers are readily available already here or via your favourite search engine.
UPDATE
If what you're really asking is "how do I refresh a local copy of a repo, overwriting mis-matched files", then I believe the following may work:
git fetch --all
git reset --hard origin/master
Or if you're on a different branch:
git reset --hard origin/branchname
The git fetch re-downloads the latest from remote without a merge or rebase (which would be done if you were to git pull).
The git reset will reset the master branch to whataver was just fetched. The --hard option changes all the files in your working tree to match the files in origin/master (or whatever branch you specify).
NOTE: This overwrites local files. Make sure to stash any local changes, as this will overwrite anything that hasn't yet been pushed. Files that are not in the repo will be left untouched, but anything that is in the repo will be overwritten with whatever is fetched, and local (unpushed) commits will be lost.

I would go for grep + xargs + sed
grep -rlI "\r\n" * | xargs -I{} sed -i.bak -e 's/\r//g' {}
grep will list non binary file that have \r\n and sed will remove the \r
I didn't try, so it may need a bit of tweeking!

Related

Laravel .gitignore blocking of generated css and js files(from `npm run *` type commands) is not effective, as it's supposed to be [duplicate]

I put a file that was previously being tracked by Git onto the .gitignore list. However, the file still shows up in git status after it is edited. How do I force Git to completely forget the file?
.gitignore will prevent untracked files from being added (without an add -f) to the set of files tracked by Git. However, Git will continue to track any files that are already being tracked.
To stop tracking a file, we must remove it from the index:
git rm --cached <file>
To remove a folder and all files in the folder recursively:
git rm -r --cached <folder>
The removal of the file from the head revision will happen on the next commit.
WARNING: While this will not remove the physical file from your local machine, it will remove the files from other developers' machines on their next git pull.
The series of commands below will remove all of the items from the Git index (not from the working directory or local repository), and then will update the Git index, while respecting Git ignores. PS. Index = Cache
First:
git rm -r --cached .
git add .
Then:
git commit -am "Remove ignored files"
Or as a one-liner:
git rm -r --cached . && git add . && git commit -am "Remove ignored files"
git update-index does the job for me:
git update-index --assume-unchanged <file>
Note: This solution is actually independent of .gitignore as gitignore is only for untracked files.
Update, a better option
Since this answer was posted, a new option has been created and that should be preferred. You should use --skip-worktree which is for modified tracked files that the user don't want to commit anymore and keep --assume-unchanged for performance to prevent git to check status of big tracked files. See https://stackoverflow.com/a/13631525/717372 for more details...
git update-index --skip-worktree <file>
To cancel
git update-index --no-skip-worktree <file>
git ls-files -c --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"
This takes the list of the ignored files, removes them from the index, and commits the changes.
Move it out, commit, and then move it back in.
This has worked for me in the past, but there is probably a 'gittier' way to accomplish this.
I always use this command to remove those untracked files.
One-line, Unix-style, clean output:
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
It lists all your ignored files, replaces every output line with a quoted line instead to handle paths with spaces inside, and passes everything to git rm -r --cached to remove the paths/files/directories from the index.
The copy/paste (one-liner) answer is:
git rm --cached -r .; git add .; git status; git commit -m "Ignore unwanted files"
This command will NOT change the content of the .gitignore file. It will just ignore the files that have already been committed to a Git repository, but now we have added them to .gitignore.
The command git status; is to review the changes and could be dropped.
Ultimately, it will immediately commit the changes with the message "Ignore unwanted files".
If you don't want to commit the changes, drop the last part of the command (git commit -m "Ignore unwanted files")
Use this when:
You want to untrack a lot of files, or
You updated your .gitignore file
Source: Untrack files already added to Git repository based on .gitignore
Let’s say you have already added/committed some files to your Git repository and you then add them to your .gitignore file; these files will still be present in your repository index. This article we will see how to get rid of them.
Step 1: Commit all your changes
Before proceeding, make sure all your changes are committed, including your .gitignore file.
Step 2: Remove everything from the repository
To clear your repository, use:
git rm -r --cached .
rm is the remove command
-r will allow recursive removal
–cached will only remove files from the index. Your files will still be there.
The rm command can be unforgiving. If you wish to try what it does beforehand, add the -n or --dry-run flag to test things out.
Step 3: Readd everything
git add .
Step 4: Commit
git commit -m ".gitignore fix"
Your repository is clean :)
Push the changes to your remote to see the changes effective there as well.
If you cannot git rm a tracked file because other people might need it (warning, even if you git rm --cached, when someone else gets this change, their files will be deleted in their filesystem). These are often done due to config file overrides, authentication credentials, etc. Please look at https://gist.github.com/1423106 for ways people have worked around the problem.
To summarize:
Have your application look for an ignored file config-overide.ini and use that over the committed file config.ini (or alternately, look for ~/.config/myapp.ini, or $MYCONFIGFILE)
Commit file config-sample.ini and ignore file config.ini, have a script or similar copy the file as necessary if necessary.
Try to use gitattributes clean/smudge magic to apply and remove the changes for you, for instance smudge the config file as a checkout from an alternate branch and clean the config file as a checkout from HEAD. This is tricky stuff, I don't recommend it for the novice user.
Keep the config file on a deploy branch dedicated to it that is never merged to master. When you want to deploy/compile/test you merge to that branch and get that file. This is essentially the smudge/clean approach except using human merge policies and extra-git modules.
Anti-recommentation: Don't use assume-unchanged, it will only end in tears (because having git lie to itself will cause bad things to happen, like your change being lost forever).
I accomplished this by using git filter-branch. The exact command I used was taken from the man page:
WARNING: this will delete the file from your entire history
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
This command will recreate the entire commit history, executing git rm before each commit and so will get rid of the specified file. Don't forget to back it up before running the command as it will be lost.
What didn't work for me
(Under Linux), I wanted to use the posts here suggesting the ls-files --ignored --exclude-standard | xargs git rm -r --cached approach. However, (some of) the files to be removed had an embedded newline/LF/\n in their names. Neither of the solutions:
git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
cope with this situation (get errors about files not found).
So I offer
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git commit -am "Remove ignored files"
This uses the -z argument to ls-files, and the -0 argument to xargs to cater safely/correctly for "nasty" characters in filenames.
In the manual page git-ls-files(1), it states:
When -z option is not used, TAB, LF, and backslash characters in
pathnames are represented as \t, \n, and \\, respectively.
so I think my solution is needed if filenames have any of these characters in them.
Do the following steps for a file/folder:
Remove a File:
need to add that file to .gitignore.
need to remove that file using the command (git rm --cached file name).
need to run (git add .).
need to (commit -m) "file removed".
and finally, (git push).
For example:
I want to delete the test.txt file. I accidentally pushed to GitHub and want to remove it. Commands will be as follows:
First, add "test.txt" in file .gitignore
git rm --cached test.txt
git add .
git commit -m "test.txt removed"
git push
Remove Folder:
need to add that folder to file .gitignore.
need to remove that folder using the command (git rm -r --cached folder name).
need to run (git add .).
need to (commit -m) "folder removed".
and finally, (git push).
For example:
I want to delete the .idea folder/directory. I accidentally pushed to GitHub and want to remove it. The commands will be as follows:
First, add .idea in file .gitignore
git rm -r --cached .idea
git add .
git commit -m ".idea removed"
git push
Update your .gitignore file – for instance, add a folder you don't want to track to .gitignore.
git rm -r --cached . – Remove all tracked files, including wanted and unwanted. Your code will be safe as long as you have saved locally.
git add . – All files will be added back in, except those in .gitignore.
Hat tip to #AkiraYamamoto for pointing us in the right direction.
Do the following steps serially, and you will be fine.
Remove the mistakenly added files from the directory/storage. You can use the "rm -r" (for Linux) command or delete them by browsing the directories. Or move them to another location on your PC. (You maybe need to close the IDE if running for moving/removing.)
Add the files / directories to the .gitignore file now and save it.
Now remove them from the Git cache by using these commands (if there is more than one directory, remove them one by one by repeatedly issuing this command)
git rm -r --cached path-to-those-files
Now do a commit and push by using the following commands. This will remove those files from Git remote and make Git stop tracking those files.
git add .
git commit -m "removed unnecessary files from Git"
git push origin
I think, that maybe Git can't totally forget about a file because of its conception (section "Snapshots, Not Differences").
This problem is absent, for example, when using CVS. CVS stores information as a list of file-based changes. Information for CVS is a set of files and the changes made to each file over time.
But in Git every time you commit, or save the state of your project, it basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot. So, if you added file once, it will always be present in that snapshot.
These two articles were helpful for me:
git assume-unchanged vs skip-worktree and How to ignore changes in tracked files with Git
Basing on it I do the following, if the file is already tracked:
git update-index --skip-worktree <file>
From this moment all local changes in this file will be ignored and will not go to remote. If the file is changed on remote, conflict will occur, when git pull. Stash won't work. To resolve it, copy the file content to the safe place and follow these steps:
git update-index --no-skip-worktree <file>
git stash
git pull
The file content will be replaced by the remote content. Paste your changes from the safe place to the file and perform again:
git update-index --skip-worktree <file>
If everyone, who works with the project, will perform git update-index --skip-worktree <file>, problems with pull should be absent. This solution is OK for configurations files, when every developer has their own project configuration.
It is not very convenient to do this every time, when the file has been changed on remote, but it can protect it from overwriting by remote content.
Using the git rm --cached command does not answer the original question:
How do you force git to completely forget about [a file]?
In fact, this solution will cause the file to be deleted in every other instance of the repository when executing a git pull!
The correct way to force Git to forget about a file is documented by GitHub here.
I recommend reading the documentation, but basically:
git fetch --all
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch full/path/to/file' --prune-empty --tag-name-filter cat -- --all
git push origin --force --all
git push origin --force --tags
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
Just replace full/path/to/file with the full path of the file. Make sure you've added the file to your .gitignore file.
You'll also need to (temporarily) allow non-fast-forward pushes to your repository, since you're changing your Git history.
Move or copy the file to a safe location, so you don't lose it. Then 'git rm' the file and commit.
The file will still show up if you revert to one of those earlier commits, or another branch where it has not been removed. However, in all future commits, you will not see the file again. If the file is in the Git ignore, then you can move it back into the folder, and Git won't see it.
The answer from Matt Frear was the most effective IMHO. The following is just a PowerShell script for those on Windows to only remove files from their Git repository that matches their exclusion list.
# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles = gc .gitignore | ?{$_ -notmatch "#"} | ?{$_ -match "\S"} | % {
$ignore = "*" + $_ + "*"
(gci -r -i $ignore).FullName
}
$ignoreFiles = $ignoreFiles| ?{$_ -match "\S"}
# Remove each of these file from Git
$ignoreFiles | % { git rm $_}
git add .
The accepted answer does not "make Git "forget" about a file..." (historically). It only makes Git ignore the file in the present/future.
This method makes Git completely forget ignored files (past/present/future), but it does not delete anything from the working directory (even when re-pulled from remote).
This method requires usage of file /.git/info/exclude (preferred) or a pre-existing .gitignore in all the commits that have files to be ignored/forgotten. 1
All methods of enforcing Git ignore behavior after-the-fact effectively rewrite history and thus have significant ramifications for any public/shared/collaborative repositories that might be pulled after this process. 2
General advice: start with a clean repository - everything committed, nothing pending in working directory or index, and make a backup!
Also, the comments/revision history of this answer (and revision history of this question) may be useful/enlightening.
#Commit up-to-date .gitignore (if not already existing)
#This command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"
#Apply standard Git ignore behavior only to the current index, not the working directory (--cached)
#If this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#This command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached
#Commit to prevent working directory data loss!
#This commit will be automatically deleted by the --prune-empty flag in the following command
#This command must be run on each branch
git commit -m "ignored index"
#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits. If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command
git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --prune-empty --tag-name-filter cat -- --all
#List all still-existing files that are now ignored properly
#If this command returns nothing, it's time to restore from backup and start over
#This command must be run on each branch
git ls-files --other --ignored --exclude-standard
Finally, follow the rest of this GitHub guide (starting at step 6) which includes important warnings/information about the commands below.
git push origin --force --all
git push origin --force --tags
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
Other developers that pull from the now-modified remote repository should make a backup and then:
#fetch modified remote
git fetch --all
#"Pull" changes WITHOUT deleting newly-ignored files from working directory
#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed
git reset FETCH_HEAD
Footnotes
1 Because /.git/info/exclude can be applied to all historical commits using the instructions above, perhaps details about getting a .gitignore file into the historical commit(s) that need it is beyond the scope of this answer. I wanted a proper .gitignore file to be in the root commit, as if it was the first thing I did. Others may not care since /.git/info/exclude can accomplish the same thing regardless where the .gitignore file exists in the commit history, and clearly rewriting history is a very touchy subject, even when aware of the ramifications.
FWIW, potential methods may include git rebase or a git filter-branch that copies an external .gitignore into each commit, like the answers to this question.
2 Enforcing Git ignore behavior after-the-fact by committing the results of a stand-alone git rm --cached command may result in newly-ignored file deletion in future pulls from the force-pushed remote. The --prune-empty flag in the following git filter-branch command avoids this problem by automatically removing the previous "delete all ignored files" index-only commit. Rewriting Git history also changes commit hashes, which will wreak havoc on future pulls from public/shared/collaborative repositories. Please understand the ramifications fully before doing this to such a repository. This GitHub guide specifies the following:
Tell your collaborators to rebase, not merge, any branches they created off of your old (tainted) repository history. One merge commit could reintroduce some or all of the tainted history that you just went to the trouble of purging.
Alternative solutions that do not affect the remote repository are git update-index --assume-unchanged </path/file> or git update-index --skip-worktree <file>, examples of which can be found here.
In my case I needed to put ".envrc" in the .gitignore file.
And then I used:
git update-index --skip-worktree .envrc
git rm --cached .envrc
And the file was removed.
Then I committed again, telling that the file was removed.
But when I used the command git log -p, the content of the file (which was secret credentials of the Amazon S3) was showing the content which was removed and I don't want to show this content ever on the history of the Git repository.
Then I used this command:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch .envrc' HEAD
And I don't see the content again.
I liked JonBrave's answer, but I have messy enough working directories that commit -a scares me a bit, so here's what I've done:
git config --global alias.exclude-ignored '!git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached && git ls-files -z --ignored --exclude-standard | xargs -0 git stage && git stage .gitignore && git commit -m "new gitignore and remove ignored files from index"'
Breaking it down:
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git ls-files -z --ignored --exclude-standard | xargs -0 git stage
git stage .gitignore
git commit -m "new gitignore and remove ignored files from index"
remove ignored files from the index
stage .gitignore and the files you just removed
commit
The BFG is specifically designed for removing unwanted data like big files or passwords from Git repositories, so it has a simple flag that will remove any large historical (not-in-your-current-commit) files: '--strip-blobs-bigger-than'
java -jar bfg.jar --strip-blobs-bigger-than 100M
If you'd like to specify files by name, you can do that too:
java -jar bfg.jar --delete-files *.mp4
The BFG is 10-1000x faster than git filter-branch and is generally much easier to use - check the full usage instructions and examples for more details.
Source: Reduce repository size
If you don't want to use the CLI and are working on Windows, a very simple solution is to use TortoiseGit. It has the "Delete (keep local)" Action in the menu which works fine.
This is no longer an issue in the latest Git (v2.17.1 at the time of writing).
The .gitignore file finally ignores tracked-but-deleted files. You can test this for yourself by running the following script. The final git status statement should report "nothing to commit".
# Create an empty repository
mkdir gitignore-test
cd gitignore-test
git init
# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial
# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore
# Remove the file and commit
git rm file
git commit -m "removed file"
# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status
This is how I solved my issue:
git filter-branch --tree-filter 'rm -rf path/to/your/file' HEAD
git push
In this, we are basically trying to rewrite the history of that particular file in previous commits also.
For more information, you can refer to the man page of filter-branch here.
Source: Removing sensitive data from a repository - using filter-branch
Source: Git: How to remove a big file wrongly committed
In case of already committed DS_Store:
find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch
Ignore them by:
echo ".DS_Store" >> ~/.gitignore_global
echo "._.DS_Store" >> ~/.gitignore_global
echo "**/.DS_Store" >> ~/.gitignore_global
echo "**/._.DS_Store" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global
Finally, make a commit!
Especially for the IDE-based files, I use this:
For instance, for the slnx.sqlite file, I just got rid off it completely like the following:
git rm {PATH_OF_THE_FILE}/slnx.sqlite -f
git commit -m "remove slnx.sqlite"
Just keep that in mind that some of those files store some local user settings and preferences for projects (like what files you had open). So every time you navigate or do some changes in your IDE, that file is changed and therefore it checks it out and show as uncommitted changes.
If anyone is having a hard time on Windows and you want to ignore the entire folder, go to the desired 'folder' on file explorer, right click and do 'Git Bash Here' (Git for Windows should have been installed).
Run this command:
git ls-files -z | xargs -0 git update-index --assume-unchanged
For me, the file was still available in the history and I first needed to squash the commits that added the removed files: https://gist.github.com/patik/b8a9dc5cd356f9f6f980
Combine the commits. The example below combines the last 3 commits
git reset --soft HEAD~3
git commit -m "New message for the combined commit"
Push the squashed commit
If the commits have been pushed to the remote:
git push origin +name-of-branch
In my case here, I had several .lock files in several directories that I needed to remove. I ran the following and it worked without having to go into each directory to remove them:
git rm -r --cached **/*.lock
Doing this went into each folder under the 'root' of where I was at and excluded all files that matched the pattern.

Git for Windows "No tags file" Response from "git diff" Command

Git version: 2.14.2.2
Whenever I run git diff on a repository I am greeted with the response No tags file. I have tried running the command on multiple repositories, multiple consoles (Cmd, PowerShell, MINGW64, Visual Studio Command Prompt) and all have the same response.
Strangely, the git log command also fails. Many other commands work, however, such as git status, git pull, etc. It seems to be only log and diff.
I have uninstalled Git entirely and reinstalled. Restarted my system. Tried referencing the git.exe directly (which yields the exact same response). Nothing is working and I have not seen this error anywhere else. I compared my user configs with those of a colleague and they are identical.
Some portion of the command executes properly, because if I supply two commit hashes, and I intentionally break one, the response I receive is:
It seems like another program may be hijacking the git diff command. I believe this because I'm not sure "No tags file" is even a possible Git response. Not sure what else it would be.
To make things even more confusing- my ultimate goal is to run the git diff within the context of an msbuild and it DOES EXECUTE CORRECTLY. Now, I could be satisfied with this, but I need to modify the diff command slightly, and running a full build each time is not productive, nor easy to troubleshoot. There is a task within the build script that runs an Exec command and it has no issues performing the diff. I'm also able to execute a Diff Against Current within SourceTree, which to the best of my knowledge, runs a git diff behind the scenes.
Any help would be very much appreciated.
:: Edits ::
Various commands:
git diff HEAD~1 HEAD
git diff master~1 master
git diff <commit-hash-1> <commit-hash-2>
git log HEAD~1..HEAD
git log master~1..master
git log <commit-hash-1>..<commit-hash-2>
Output:
Every one of the commands above returns the same No tags file response, in all of my repos.
Cat Head:
cd .git
cat HEAD
ls -R refs
Output:
New Repo:
mkdir testrepo
cd testrepo
git init
echo "file1" > file1.txt
git add .
git commit -m "initial commit of file1.txt"
echo "Hi there!" > file2.txt
git add .
git commit -m "added file2.txt"
git log
git diff HEAD~1 HEAD
Output:
git config -e:
git config --global -e:
::Edits 2::
I uninstalled all of my diffing/source control tools (SourceTree, Git, SVN, WinMerge, KDiff). Installed the portable version of Git. Opened CMD to a repo, put in full path to the git.exe portable and it still returned the No tags file response.
I also reviewed all of my path variables for: git, vim, ming, mintty and anything else that seemed suspect, but didn't find any.
I have restarted after performing all steps, and yet the problem persists.
::Edits 3::
I have a different user on my laptop, switched to that user and the git diff works properly, so clearly there is something with my main user that is conflicting. Will continue to look into my User directory for issues.
Here are the steps I'd take in this situation:
Try the following and check the response:
git diff HEAD~1 HEAD
git diff master~1 master
git diff <commit-hash-1> <commit-hash-2>
Try the same with log:
git log HEAD~1..HEAD
git log master~1..master
git log <commit-hash-1>..<commit-hash-2>
I'm actually guessing that your refs are messed up, which means that the direct hashes might work, but the HEAD and/or master one may not.
Look into the .git/refs folder
From the main repo folder:
cd .git
cat HEAD
ls -R refs
Hopefully, HEAD is pointing to a branch, and if master is checked out, cat HEAD output should look like:
ref: refs/heads/master
Then, the ls -R refs, should show a heads folder, with files for each of your local branches (i.e. master and possibly others). You also likely have refs/remotes and refs/tags directories.
If any of these things are radically different or missing, that could be your issue...
Since you have reinstalled git, create a brand new repo and try the same commands:
mkdir testrepo
cd testrepo
git init
echo "file1" > file1.txt
git add .
git commit -m "initial commit of file1.txt"
echo "Hi there!" > file2.txt
git add .
git commit -m "added file2.txt"
git log
git diff HEAD~1 HEAD
If this last one works, then git is likely working okay, but some tool you have is messing things up.
Post your config from git config -e and git config --global -e - maybe we can see something?
When googling for the "No tags file" message, the first results I get all talk about vi.
I do not understand why git would try to execute vi when running git diff or git log, could it be that your system is configured to use vi as a pager ?
# some possible places which could influence that :
echo $PAGER
echo $GIT_PAGER
git config --get core.pager
When digging in the documentation for less, I found that less can use a ctags file, to spot "the file that contains this tag".
So you can also look at the list of variables that influence the behavior of less :
# from bash :
# env will list all the defined environment variables
env
# the ones that impact 'less' should contain "LESS" in their names :
env | grep LESS

.gitattributes don't work properly on mac and windows

On my project i use computers with different OS, one is Mac second is with windows. When I use git every change is shown as whole document change. The reason is different end-of-line in these two OS. I read this https://help.github.com/articles/dealing-with-line-endings/ and made a .gitattributes file in the root folder but the problem still exists. This is my .gitattributes file:
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.css text
*.html text
*.js text
# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
I have no idea why it's not working because I was try a lot of configurations of this file before.
The .gitattributes file should be added with the first commit. If you add it a few commits in, you need to normalize all the existing files explicitly.
$ rm .git/index # Remove the index to force Git to
$ git reset # re-scan the working directory
$ git status # Show files that will be normalized
$ git add -u
$ git commit -m "Introduce end-of-line normalization"
See https://git-scm.com/docs/gitattributes
If .gitattributes file was not added with the first commit, the following should be performed to apply attributes locally:
Go to the root of the repository
Check status:
git status
If it says "nothing to commit, working tree clean", perform:
git rm --cached -r .
git reset --hard
The answer is based on https://dev.to/deadlybyte/please-add-gitattributes-to-your-git-repository-1jld

On Windows git can't handle files with the same name but in different case properly

I use git on windows. In my project I changed case of filename. After that checkout of previous commits failed (commands are in Git Bash):
mkdir repofolder
cd repofolder
git init # create empty repo
git config core.ignorecase false # turn on case-dependent filenames
# create 'readme.txt'
$ echo "blahblahblah" > readme.txt
$ git add readme.txt
$ git commit -m "+readme.txt"
# rename it to 'README.txt'
$ git mv -f readme.txt README.txt
$ git commit -m "readme.txt => README.txt"
$ git status
On branch master
nothing to commit, working directory clean
$ git checkout HEAD~1
error: The following untracked working tree files would be overwritten by checkout:
readme.txt
Please move or remove them before you can switch branches.
Aborting
Why git doesn't allow to checkout previos commits?
You face with the same problem when delete one file and append another one with the same name, but different case. No matter how many commits you do: one (removing and appending in the same commit) or two commits (in first commit you remove file, in second you add another one).
On Windows git can't handle files with the same name but in different case properly
Git on Windows can't handle it because Windows itself can't handle it (emphasis mine):
As part of the requirements for POSIX compliance, the Windows NT File System (NTFS) provides a case-sensitive file and directory naming convention. Even though NTFS and the POSIX subsystem each handle case-sensitivity well, 16-bit Windows-based, MS-DOS-based, OS/2-based, and Win32-based applications do not.
In truth, Windows does have some level of support for NTFS case-sensitivity, but it's pretty flaky:
However, if you attempt to open one of these files in a Win32 application, such as Notepad, you would only have access to one of the files, regardless of the case of the filename you type in the Open File dialog box.
Other inconsistencies also exist. The Windows NT Command Prompt and File Manager correctly display the names of the files. However, normal commands, such as COPY, fail when you attempt to access one or more filenames that differ only in case.

Git: File Rename

I wanted to rename a folder from "Frameworks" to "frameworks", but git would not let me add the new lowercase name. I guess it treats filenames case insensitive, does it?
A git add frameworks/ -f didn't help
You can try:
"git mv -f foo.txt Foo.txt" (note: this is no longer needed since git 2.0.1)
to set ignorecase to false in the config file.
But the issue of case (on Windows for instance) is described in the msysgit issue 228 (again: this should now -- June 2014 -- work with git 2.0.1)
there is always an option to set ignorecase to false in the config file that will force Unix like Git semantics on top of NTFS.
Git supports this behavior but it is not the default - from NTFS point of view a.txt
and A.txt are the same thing - so Git tries to preserve that as most users would expect
As a better workaround, you can
git mv foo.txt foo.txt.tmp && git mv foo.txt.tmp Foo.txt
, which also changes the case of the file as stored on disk.
This blog post illustrates the same issue on MacOs during a rebase:
The default on Mac OS X file systems is that they are case-insensitive. FFFFFF.gif is the same as ffffff.gif.
If you delete the file in question, just from the file system, not from the Git index, mind you, you can merge the branch in question, and have it restore the file as if nothing happened.
The steps are pretty simple:
$ rm file/in/question.gif
$ git merge trunk
Anyhow, remember what git mv stands for:
mv oldname newname
git add newname
git rm oldname
, so if newname and oldname clash, you need to make them different (even if it is only for a short period of time), hence the git mv foo.txt foo.txt.tmp && git mv foo.txt.tmp Foo.txt
If you happen to host on Github, you can use the rename function on their website. Had to change the casing for 5 files and found it worked really well.
I was having a similar problem and couldn't get a new folder name (different case) to change on remote repos. I found that the easiest solution was just to move the file out of the repo and commit. Triggering a delete action. Then re-add and when I added, it came in with the proper case.

Resources