git : reverts changes other than one specific files - linux

git revert HEAD reverts all changes, but what I want to revert the ones except my go extension files? I want to revert all changes except the one with *.go
I tried
git revert HEAD ^*.go
git revert HEAD *.go?
None of them works. Where should I look up to find this feature?
Thanks~!

There may be a better way, but what should work:
git revert --no-commit HEAD
git reset HEAD -- *.go
git checkout -- *.go`
git commit
Or you can approach it the other way around and instead of using revert, checkout the files you want to revert from the old commit:
git checkout <commit> -- <paths to revert>
git commit

I am by no means an expert with piping output into Git commands, but you could try something along the lines of:
git checkout HEAD^ -- $(find. -not -path '*.git*' -not -iname '*.go' -type f)
The find output should consist of all the files that do not have the go extension. These files will then be reverted to their state in the last HEAD. You may need to add additional -not chunks for folders or files you want to ignore.

Related

find all lines with specific phrase in specific commit

Lets assume I have a commit with a known hash, and the commit touches 1000 files of 5000 files of the project.
Among some of those files there was added the log message LOG_WARNING(...);, lets say 500 times. Which I want to replace by LOG_INFO(...);.
I don't want to replace all LOG_WARNING(...); in the project (lets say it has 10000 of them), just ones, related to the specified commit.
I'm ready to walk over each of 500 lines I have to modify, but I'm trying to avoid walking over 10000 existing log-lines in the codebase.
What is the best way (practice) to do it?
I would do it that way:
git show --name-only <commit> | xargs sed -i 's/LOG_WARNING/LOG_INFO/'
The git command give the filenames part of the commit.
xargs provides these files to sed which replaces the wanted pattern.
What did help to me:
git diff (...) > patchfile -- extract all changes of current commit to a patchfile
edit patchfile -- using any editing tool & script, but in the patchfile I had to deal with only LOG_WARNING of specified commit.
git reset --hard -- to get rid of the commit I'm going to modify
git apply patchfile -- applies "patch", containing exactly my commit, but with replacement I wanted to.
It does the job. And relatively quickly.

What files am I working on?

A question I frequently ask my terminal is:
What files am I working on? (including committed files)
The answer is usually gotten by this command
git diff my_current_work_branch..master_branch | grep diff
this gives me a crude list of files that I'm currently working on.
Is there a more elegant way to get this info? All I want to ask git is,
what files does this branch add/modify/delete, relative to the master branch.
You can use git diff. If all you want is the names of files that differ, you can use the --name-only.
git diff --name-only master my_branch
or if you're actually checked out to my_branch
git diff --name-only master HEAD
or if you want to include uncommitted changes
git diff --name-only master
diffstat is a handy tool
git diff my_current_work_branch..master_branch` | diffstat -l
will show you each file that's been modified in the diff output.

Creating a zip file of files from repo for revert purposes

My normal process for deploying to an FTP server from git is this:
git status
git add .
git commit -m "Message"
zip update.zip $(git diff --name-only HEAD^) creates a zip file.
git push origin master
The zip file that is created is a list of all the updated files with their paths.
I'd like to do something similar that creates a zip file with the same content but instead listing the files before they were changed (so the previous commit for each). This way if there is any issue with any of the files I can quickly revert the changes.
Any suggestions?
First of all, instead of your zip update.zip $(git diff --name-only HEAD^) you can use git archive --format=zip -o update.zip which won't fail if you have whitespaces in your filenames. This command also take <tree-ish> parameter which is tree or commit to produce an archive for.
I do not quite understand what you are trying to achieve, but instead your (quietly complicated) workflow I would think about using something like git-ftp.

Git delete all unmodified files

I am using git in my project at Linux platform. I have plenty of files in a particular directory. I modified some 50 above files in that directory and didn't stage and commit it. I wish to delete all other unmodified files from that directory? Is there a way to do this, using git and Linux Commands?
Not sure why you would want to do this.... but you can:
# Save changes to stash
git stash save
# Remove everything left
rm -rf ./*
# Checkout (restore) all of the changed files
git stash show --stat | grep -v changed | sed -e 's/|.*$//;' | xargs git checkout
# Restore the changes to those files
git stash pop
git reset --hard [HEAD] should work for you repeated
Repeated question How can I discard modified files?
You can also use more simple commands for this purpose:
git clean -Xfd // capital X
git clean -xfd // lower x
It will clean your working directory from the desired files.
Using git clean is what you want. To remove (-x) those files and directories (-d), run:
$ git clean -fdx
If you use the -X option instead of -x, then the files you have told git to ignore will still be kept (e.g., build artifacts). Recent versions of git require either "-f" (force) or "-n" (dry-run) to be specified.
You should run a dry-run first, to show what will happen, but not actually do anything:
$ git clean -ndx
I use this so often, that I have an alias for this (added to your .gitconfig) to check for files that would be deleted when you run git clean. It's also useful to remind me if I've forgotten to "git add" a file that I want to keep.
[alias]
# list files that would be removed via 'clean' (non-destructive)
ifc = clean -ndx
Then, running git ifc (i.e,. "ifc" = "if clean") shows everything that isn't tracked and could be removed, or isn't tracked and should be added.
https://git-scm.com/docs/git-clean

How to apply a git patch on a non-checked out branch?

I am wondering if it is possible to apply a git patch on a non-checked out branch?
I would like to do this because I don't want this patch on my working branch, but on a dedicated branch that I don't use right now. This is a large branch, and checking it out will:
make my exuberant tags useless or broken. It takes long to rebuild them.
also, my kernel will force rebuild if I checkout this branch and roll-back to my working branch...
It's extremely indirect, but possible. You can do it by applying it only to the index.
The easy way:
$ git read-tree <branch>
$ git apply --cached <patch>
$ git update-ref refs/heads/<branch> \
-m "<optional reflog message>" \
$(git commit-tree $(git write-tree) -m "<message>" -p <branch>)
If you want everything to be "cleaner" (i.e. have the reflog look normal for the commit), then here's a longer way, considerably more verbose:
$ git checkout -b temp # Create a temp branch
$ git reset --mixed <branch> # Reset the index to the branch you want
$ git apply --cached <patch> # Apply the patch to the index
$ git commit # Create a commit object
# Move the branch's reference to the new commit
$ git update-ref refs/heads/<branch> refs/heads/temp
# Clean up
$ git checkout --force <original_branch>
$ git branch -d temp
Can you clone from your current repository to another directory, and check out the branch you want to work on there? AFAIK, you can only apply a patch, or cherry pick commits, etc. to the files in your working directory.
For some of the projects I work on, I have multiple copies of a repository on my system, with different branches checked out on each.
I don't think this is possible mainly because of this reason:
How will you deal with a patch failure?

Resources