How to check if a file in git commit is a symbolic link without checkout - linux

Is there a way to check if a file in git commit is a symbolic link without checking out the commit content?
Background:
There is a hook which is used to check C++ code formatting in each git commit that is pushed.
So far the algorithm is:
Get a list of files in a commit with git diff-tree --no-commit-id --name-only --diff-filter=d -r ${commit}.
Processes each file (content) in git commit, selected based on a file extension, using git show ${commit}:${file}.
Problem:
A file with .cpp extension may be a symbolic link, in which case it shall not be processed.
NOTE: I know that having source files as a symbolic link is not a good idea.

Related

git sparse-checkout ignore specific file type

I have a git repository with a bunch of large csv in them, which I don't want to clone, so I came across git sparse-checkout and this post: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/
From this post I took following:
git clone --no-checkout https://github.com/john_doe/repo-with-big-csv.git
cd repo-with-big-csv
git sparse-checkout init --cone
Then I edit the .git/info/sparse-checkout and add the following (adapted from example in page above):
/*
!**/*.csv
But it doesn't seem to work properly. After git pull some folders are cloned, some are not. I also noticed a warning, when I do git sparse-checkout list I get:
warning: unrecognized pattern: '**/*.csv'
warning: disabling cone pattern matching
/*
!**/*.csv
What's the proper way to ignore a certain file type only?
See "Git sparse checkout with exclusion" and make sure to use Git 2.26.x, which has some fixes for the git sparse-checkout command.
When in cone mode, the git sparse-checkout set subcommand takes a list of directories instead of a list of sparse-checkout patterns
If core.sparseCheckoutCone=true, then Git will parse the sparse-checkout file expecting patterns of these types. Git will warn if the patterns do not match.
You need to only use restrict patterns based on folder prefix matches.
The OP Frode Akselsen adds in the comments:
my example is actually working: the folders that don't show up just contain only .csv files, hence, after applying the rules in .git/info/sparse-checkout, nothing is in the folder anymore and therefore Git doesn't show the folder.
I confirm Git will only show content: if folder has no file (no "content"), said folder is not visible.

How to get all deleted local files from remote using GIT

I have a local directory with multiple files. These files
are already stored in remote git (BitBucket).
I accidentally deleted these files locally, how can I
get it back from the remote repository?
You don't need to get them from remote if you already had those files locally.
You can use:
git checkout -- <deleted file name>
You can also use file and directory wildcards:
git checkout -- dir1/*
git checkout [<tree-ish>] [--] <pathspec>...
Overwrite paths in the working tree by replacing with the contents in the index or in the <tree-ish> (most often a commit). When a <tree-ish> is given, the paths that match the <pathspec> are updated both in the index and in the working tree.
Did you commit the deletions?
If not, you can use git checkout -- file to recover the files.
If you did, you can git reset to a previous commit where the files still existed.
If you need a more fine-tuned approach, you can git clone your remote repository to a new directory and then use file operations to copy files from the copy to your original repository.
You can reset your local master branch to the remote repo master like so:
git fetch
git reset --hard origin/master
If you just deleted the file and do not run git add, then
git checkout -- <file>
If you have run git add, then
git reset HEAD <file>
git checkout -- <file>
If you have commit it to local repository, then
git reset --hard <the_commit_before_bad_commit>
Anyway, you'd better backup all the files when you try it.

How do I "extract" my commited files?

I have two files file1.c and file1.h in my working directory /tmp/working. Everything I do is on my local file system.
I do a git init in /tmp/working that creates a .git directory in it. Then I git add file1.* and git commit -m "Feb 13th 2017".
On Feb 17 I accidentally delete the two files in my working directory. How do I restore my files in my working directory from my local git repository? I don't want to undo the last commit or something like that, just want the copy of my files (version of Feb 13th) back in my working directory.
You can try just checking out those two files from the latest commit:
git checkout -- path/to/file1.c
git checkout -- path/to/file1.h
The nice thing about Git is that it is hard to really mess things up. You only deleted those two files locally in the current commit. But their history is easily accessible using git checkout.
Actually, any path works:
git checkout -- path/to/ # extracts the whole "path/to" directory
git checkout -- . # extract all the content of the last commit
and you can also specify any commit :
git checkout other_branch -- path/to/ # extracts content from other_branch
git checkout v1.7.3 -- path/to/ # from this tag
git checkout eacf33b -- path/to/ # from this commit

Git ignore and changing the history (on Windows)

I've already read several posts about this here (like Git ignore & changing the past, How to remove files that are listed in the .gitignore but still on the repository?, and Applying .gitignore to committed files), but they have several problems:
Commands that only work on Linux.
Incomplete commands (like the first post I've linked to).
Only for one file.
I have pretty much no experience with Git so I was hoping for some help here.
What I'm basically trying to do is rescue one of my projects history. It's currently Hg and I converted it to Git with Hg-Git (all very easy) and it includes the history (great!). However, I also added a .gitignore file and added several new files & folders that I want completely gone from the history (like the bin and obj folders, but also files from ReSharper). So I'm looking for a way to apply the .gitignore file to all of my history. The commands should work on Windows as I have no intention of installing Linux for this.
No need to add the .gitignore in the history (there is no added value to do it), just add it for your future commits.
For the remove of files and directories in your history, use bfg-repo-cleaner which is fast, easy and works very well on Windows (done in scala).
It will do the job for you!
This is working for me:
Install hg-git.
cd HgFolder
hg bookmark -r default master
mkdir ../GitFolder
cd ../GitFolder
git init --bare
cd ../HgFolder
hg push ../GitFolder
Move all files from GitFolder to a '.git' folder (in this GitFolder) and set this folder to hidden (not the subfolders and files).
cd ../GitFolder
git init
git remote add origin https://url.git
Copy all current content (including .gitignore) to GitFolder.
git add .
git commit -m "Added existing content and .gitignore".
git filter-branch --index-filter "git rm --cache d -r --ignore-unmatch 'LINES' 'FROM' 'GITIGNORE'" --prune-empty --tag-name-filter cat -- --all
git rm -r --cached .
git add .
git gc --prune=now --aggressive
git push origin master --force
There is probably an easier way to do this and it might not be perfect but this had the result I wanted.

"git add" returning "fatal: outside repository" error

I'm just entering into the wonderful world of git.
I have to submit a bunch of changes that I've made on my program, located in a directory called /var/www/myapp.
I created a new directory /home/mylogin/gitclone. From this directory, I did a git clone against the public repo and I was able to get the latest copy created.
I'm now trying to figure out how to take all the files in my working folder (/var/www/myapp) and "check them in" to the master repository.
From /home/mylogin/gitclone, I tried git add /var/www/myapp but I'm getting an error that the folder I tried to add is outside the repository.
Can you give me a few pointers on what I'm doing wrong? Also, I'd like to add everything, whether it's different from the master or not.
Thanks.
First in the clone folder you can create a Branch (so the master stay untouched)
git branch [branch_name]
After, just copy the files you want from your old folder to the clone folder.
When you are done, just add / commit your change and Merge your branch into the "master" branch. It will look like to something like this:
git add .
git commit -m "Comments"
git checkout master
git merge [new_branch]
Try this tutorial from GitHub.
You'll have to move all the files from /var/www/myapp to /home/mylogin/gitclone and then do a git add . and then git commit -m "Your message".
When upgraded to git version 2.12.2 that error appeared, I nooted the i add the file with a full path like:
git add c:\develop\project\file.text
when removed the full path it start working, like:
git add file.text
To add some files or folder to your repository, they have to be in the folder you created with git clone. So copy/paste your application in your local git folder and then go in it and do git add * and then you'll be able to commit to the server with git commit -m 'message' and finally push the changes to the server with git push
Okay, this error came up for me because I moved the project from one computer to another.
So the git was not able to figure my global git user.name and user.email
I opened the command prompt and specified my old git user.name and user.email from previous computer. Kindly run the following commands and it should be fixed.
cd pathToMyProjectDirectory
git config user.name "myName"
git config user.email "myEmail"
That's because you are versioning stuff inside /home/mylogin/gitclone and git tracks everything inside that folder. You cannot track other folders outside of this repository.
A solution might be create a submodule, or using a symbolic link using ln -s
Git only tracks files and folders within the root folder which includes the .git directory and the subfolders inside root folder. The folder you are trying to add is outside the scope of git.
What would you actually like to do is first git checkout -b myapp which will create and checkout a new branch based on the master branch of the repository you cloned. Then you would actually copy all your files over and commit them with git commit -a -m "Short descriptive name about what you did". The parameter -a you passed to git commit is for including all the changes done to the repository and -m is to include the commit message in the actual command. After that you can either push back to the main repository if you have write access to it or push it to your own public repo or don't push it at all.
What I've described above is pretty much the basics of git. Try reading this book which is pretty descriptive.
Maybe someone comes along having the same trouble like I had:
In my case this error was thrown while using husky (commit hooks) https://github.com/typicode/husky
It was just an error because of encodings. My source was located in a directory that contains a special character ("รถ")
Seems like husky uses "git add" with the absolute path of the source which fails somehow at this point
I renamed the path and it worked fine.
This message can also appear when the file name is listed in the .gitignore file.
My scenario is that the git repository's path has symbolic link and git throw out this error when add file say to "/home/abc/GIT_REPO/my_dir/my_file".
and "/home" is actually a softlink to "/devhome".
code ninja gave me some light when I tried to debug this case.
So I tried get the target directory by using the command readlink -f /home/abc/GIT_REPO before run add command.
And then everything works like a charm !
I encountered the issue at Windows box with maven-release-plugin.
The plugin tries to add files using absolute path and I have noticed that the path in the Git add command starts with uppercase D: while the path in Working directory: log line started with lowercase d:
I have added core.ignorecase = true to the Git settings and the issue was gone.

Resources