Git ignore and changing the history (on Windows) - linux

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.

Related

Git tracking to wrong local directory

I created a new directory 438-healthme and cloned a repo into it.
When I index into that directory on the master branch and run a git status it lists all of my computer's files as untracked (see screenshot).
It seems like I set up git wrong a few years ago--is there a way to fix this?
You must have run git init in a folder. You need to find it and run rm -r .git.
Try again, removing that folder, and recreating it with:
git clone https://url/remote/repo 438-healthme
Then, in 438-healthme, there should be a .git subfolder, which means a git status (in the newly created 438-healthme folder) will show you files only from 438-healthme.

Download files from git repo on linux server

I have seen so many articles/questions on how to download specific files from git repo, but none of them seems to match with my case.
What I need
Download spefic files from private git repository either using http's or ssh from linux server
Update - I originally wrote this as a general answer about git, and will preserve that info below. But I see you're talking about github, which does give some additional options.
For example, you could use a command like
curl https://raw.githubusercontent.com/eirslett/frontend-maven-plugin/master/README.md > README.md
to download just the README.md from the frontend-maven-plugin (which I happen to be looking at just now).
You mention yours is a private repo, so you'd have to deal with authentication; I suggest reading up on curl, as it should be able to provide credentials to the repo.
https://curl.haxx.se/docs/manpage.html
Original answer
There's not really a single git command for downloading an individual file from within a remote git repo. The closest I know you can do is this:
First clone the repo without checking out a work tree
git clone -n <repo-url>
Then check out just the file you want
git checkout master -- path/within/repo/to/file
But don't be fooled: This still downloads the entire repo. (That's just how git works.) So in addition to getting ./path/within/repo/to/file you also got ./.git containing all the rest of the data.
You can do in this hackish way: ö(å_å)ö
If this file is on github.com do this.:
wget https://example.githubproject.com/user/project/master/README
You can try git archive command:
git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)
Create a tar archive that contains the contents of the latest commit on the current branch, and extract it in the /var/tmp/junk directory.
Example git archieve command usage:
git archive --format=tar --remote=origin HEAD | tar xf -
git archive --format=tar --remote=origin HEAD <file> | tar xf -
Tip in using, git archive, Examples.
I'm not sure what about your question is, but, have you did git clone <<url of git project>> ??

svn2git - "hot migration" preserve file permissions

We are migrating SVN to Git. On a project.
Everything is well but I have a problem with preserving the permissions (file mode) of some untracked (ignored) dirs and files.
We the following process:
CleanUp the SVM repo (tidy up, clean uncommited stuff and so forth)
svn2git on local environment (migrating from networked SVN - so latest rev, no further commits, this does include a proper authors.txt mapping and proper tracking of branches, tags, etc.)
Create ignored files & dirs li (.gitignore)st - partially automated from svn propget, manual finish (row by row)
Add the remote and push to it (We're using github but it should hardly matter)
At this stage the remote is ready, all the history is converted. Now comes the hard part I want to hot-migrate the server deployments without changing the dirs, moving files or creating symlinks.
Let's say there are two mirrored environments are on two different servers - one for beta and one for prod. Let us say the dir is /var/www/depl/ for example/. The thing is that as every Web project, there are dirs and files that we don't need to track.
I will be writing my steps wit the commands since I think it could also be a nice guide for others.
So the strategy for on the servers is:
Go there cd /var/www/depl/
BackUp to another dir via rsync and preserve the permissions as they are!!
Delete all .svn directories recursively find -type d -name .svn -exec rm -rf {} \;
Init an empty git repo git init (notice we're not using a 'bare' repo)
Add the GitHub remote and call it "origin", also download all branches git remote add -f https://github.com/ORG/REPO
Check status (the local copy should be clean)
Pull (so fetch + merge but it is actually only a merge) git pull origin master
This last step is what breaks my permissions. Remember those files that I don't want/need to track? It now seems that those have their permissions modified.
They are all properly ignored but when I apply the pull/merge it breaks.
OK, for sure the issue is coming from the remote repository and via the merge. And it is not an issue, but rather how the files were commited (with what file modes).
The question is:
At the last step, when pulling the updates in, can I instruct git to preserve the current file permissions for all files? As in the current dir and recursively down?
So: do not change any local permissions?
Yes, maybe I will have a diff and stuff to commit afterwards, but that is not such a big issue as are the broken permissions.
So? Is there a way? The servers are running Linux of course.
Thanks in advance.
Cheers!
Well, I managed to find a way. The 'secret', as I thought, was in using rsync.
I actually solved my issue, while I was writing the question. :)
Anyway, after some research it turns out that rsync --archive will update the target's permissions provided that the timestamps didn't change. The SAMBA mailing list helped a lot!
A prerequisite is that you ensure that NOTHING WILL CHANGE in those dirs - so put the website in maintenance mode, stop all crons. Make it inaccessible so you don't have headaches later.
The migration (after you have migrated all you history into git) steps are as follows:
Take your production env to the SVN stage that you desire - update, checkout etc. Make sure that this is the same as the incommig git copy and/or keep your changes in patches.
BackUp the deployment directory with rsync rsync -av --progress /var/www/depl/ /var/www/deplBackUp1/ - notice that this includes the .svn dirs
Delete the .svn dirs: cd /var/www/delp/ find -type d -name .svn -exec rm -rf {} \;
Now backUp again in a different location rsync -av --progress /var/www/depl/ /var/www/deplBackUp2/ - the goal is to have two copies
Init the new git repo git init
Add a remote git remote add -f REMOTE_NAME https://github.com/ORG/REPO
Pull everything in from the branch you desire git pull origin master
Now rsync back from your (no-.svn dir backUp) rsync -av --progress /var/www/deplBackUp2/ /var/www/depl
You may also want to look into using bare git repositories for your server deployments.
This last step will fix any file mode issues you may have created with your new VCS.
If you ever need to do this and run into trouble, tag me in a comment - I will try to help.
Cheers!

can git be run with less file permissions than the files it tracks?

here is the situation: i want to use git to track a directory of preference files that are owned by root.
it would be nice if git commands that don't modify the files (like git status and git diff) can be run as the user (without sudo).
through the following steps, i've created a repo that seems to function in a reasonable manner:
sudo mkdir .git
sudo chmod <user>:<group> .git
git init
git add .
git commit -m "initial commit"
i can run git status and git diff as the user. git checkout ... and git reset ... fail as the user, but seem to run fine when prefixed with sudo.
this seems perfect: no sudo needed to get into the repo and take a look at what's gone on, but to change the tracked files requires an extra level of effort, as it should for system files.
the question is: will this cause me any problems with how git is reading and writing files inside the .git directory? will any commands i need sudo to run end up creating things inside .git with root permission that will then cause problems trying to run commands that don't modify the tracked files as the user?
thanks and advance for any answers.

"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