reversing commits in git - ios

I committed a change locally with Storyboards for iOS. I have not been able to merge them correctly with a friend of mine so I'm giving up. My changes are pretty small and I can redo them later. What I'd like to do is reverse the last commit without the storyboards and just keep my code. I tried following this:
How to undo last commit(s) in Git?
how i interpreted this was:
git reset --soft HEAD^
after this, I did git status, and I saw all my files in green in the staging area, including the storyboards. So i wanted to unstage them (or so I thought). So I did
git reset HEAD MainStoryboard*
Then I did not see my storyboard files on git status. I didn't see them in red either in the unstaged area which I thought was weird. So I then did
git commit -a -c ORIG_HEAD
It allowed me to change my commit message, but the commit was the same. It still commit my storyboard files. So I'm unsure of what is going on here.... Any thoughts? Thanks in advance.

when doing reset, try to use -- to separate file list from revisions
git reset HEAD -- file_list
also use simple commit (not ammend form)
git add your_changed_files
git commit

if unstaging a pattern doesn't work, you can try the approach in "GIT: I want to unstage all files matching a certain pattern":
for i in `git status --porcelain | grep '^M.*MainStoryboard.*$' | sed 's/^M \+//'`; do
git reset HEAD -- "$i"
done

Related

Is there a Git config setting to auto-signed-off-by my commits? [duplicate]

I'm looking for a way to write the Signed-off-by: tag automatically when I commit.
I tried configuring it through the .git/config file (Reference). I put these lines of code:
[alias]
commit = commit -s
This did not work. As commented below, you can not edit git's own alias (like commit).(Reference)
I also tried using the command (Reference):
git config --global format.signoff true
Also had no effect. This explains why.
I'm looking for any solution that automatically places the tag and allows me to edit the commit message directly on git, without having to use a system alias.
[Edit made after last comment]
I think if I am guessing correctly then, you cannot alias using words which are 'reserved' words for a git command.
However if you do something like this
[alias]
ci = commit -s
Then it will do what you want it to do.
Use the commits hooks to achieve this
https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_committing_workflow_hooks
prepare-commit-msg
The prepare-commit-msg hook is run before the commit message editor is fired up but after the default message is created.
It lets you edit the default message before the commit author sees it.
This hook takes a few parameters: the path to the file that holds the commit message so far, the type of commit, and the commit SHA-1 if this is an amended commit.
This hook generally isn’t useful for normal commits; rather, it’s good for commits where the default message is auto-generated, such as templated commit messages, merge commits, squashed commits, and amended commits.
You may use it in conjunction with a commit template to programmatically insert information.
You can use commit.gpgSign option
you can add it per repository by issuing the command below in the repo folder:
$ git config commit.gpgSign true
or for all git repository on your machine:
$ git config --global commit.gpgSign true

How can I force "git commit -s" using "git commit" command?

I'm looking for a way to write the Signed-off-by: tag automatically when I commit.
I tried configuring it through the .git/config file (Reference). I put these lines of code:
[alias]
commit = commit -s
This did not work. As commented below, you can not edit git's own alias (like commit).(Reference)
I also tried using the command (Reference):
git config --global format.signoff true
Also had no effect. This explains why.
I'm looking for any solution that automatically places the tag and allows me to edit the commit message directly on git, without having to use a system alias.
[Edit made after last comment]
I think if I am guessing correctly then, you cannot alias using words which are 'reserved' words for a git command.
However if you do something like this
[alias]
ci = commit -s
Then it will do what you want it to do.
Use the commits hooks to achieve this
https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_committing_workflow_hooks
prepare-commit-msg
The prepare-commit-msg hook is run before the commit message editor is fired up but after the default message is created.
It lets you edit the default message before the commit author sees it.
This hook takes a few parameters: the path to the file that holds the commit message so far, the type of commit, and the commit SHA-1 if this is an amended commit.
This hook generally isn’t useful for normal commits; rather, it’s good for commits where the default message is auto-generated, such as templated commit messages, merge commits, squashed commits, and amended commits.
You may use it in conjunction with a commit template to programmatically insert information.
You can use commit.gpgSign option
you can add it per repository by issuing the command below in the repo folder:
$ git config commit.gpgSign true
or for all git repository on your machine:
$ git config --global commit.gpgSign true

Why do I get an Large File Warning from Github for a file that i have listed in gitignore?

Without really thinking about it, I've been committing and then pushing to my Github repository the images I am using in development.
After discovering that this was causing issues that prevented me from pushing my project to my branch, I searched for a solution to remove those images from my repository then add those images to my gitignore file.
I found several solutions: StackOverflow, this blog, git and a few others. They all seemed to be pushing me the same way:
git rm --cached -r /public/uploads/image/file/**
I've run a few variations of this code, like dropping **, file/**, --cached, and image/file/**, but it doesn't change the fact that I can still see the files on my GitHub branch.
Also I've added this to my gitignore file: /public/uploads/image/file/**
But when I push to the repository branch I get this info telling me why I can't push to Github:
I started from git add . for context.
ruby 2.3.3-p222
╳ project_name categories ◆ git add .
ruby 2.3.3-p222
╳ project_name categories ◆ git commit -m "trying to get a commit in after purging development environment image data"
[categories 8c13b0a] trying to get a commit in after purging development environment image data
1 file changed, 1 insertion(+), 3 deletions(-)
ruby 2.3.3-p222
╳ project_name categories git push origin categories
Counting objects: 3840, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3664/3664), done.
Writing objects: 100% (3672/3672), 163.83 MiB | 3.98 MiB/s, done.
Total 3672 (delta 1242), reused 0 (delta 0)
remote: Resolving deltas: 100% (1242/1242), completed with 57 local objects.
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: 85ba931580b369a222fcf5903416f84e
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File public/uploads/image/file/30/show_55MiEk4_-_Imgur.gif is 119.49 MB; this exceeds GitHub's file size limit of 100.00 MB
To git#github.com:Lenocam/project_name.git
! [remote rejected] categories -> categories (pre-receive hook declined)
error: failed to push some refs to 'git#github.com:Lenocam/project_name.git'
So, now I'm confused because doesn't adding /public/uploads/image/file/** to my gitignore file tell git to ignore the folder and the files inside of it? Why does the file continue to be pushed to my repository?
It seems to me I've asked git/Github to get rid of those old files(through the terminal command) and completely forget they ever existed so they will stop asking me about them(through gitignore).
I assume I've done something out of order or otherwise incorrectly. Any assistance you're able to give me will be appreciated.
.gitignore doesn't really ignore files
In Git, a file is tracked if and only if it is in the index.1
If a file is in the index and you make a new commit, that file goes into the commit. This happens regardless of whether the file name is in .gitignore.
Once a file is in a commit, it is in that commit forever. The only way to avoid it is to stop using that commit entirely.
What .gitignore does is to make Git stop whining. For each file you have in the work-tree,2 but not in the index, Git complains: "hey, this file is in the work-tree but not in the index! Maybe you should add it!" But some files that do belong in the work-tree do not belong in any commit, and hence should never go into the index.
Putting the file—or a matching glob pattern, e.g., anything using * or **—into .gitignore tells Git: "Don't complain, and also, if it's not already in the index, don't automatically add it either with git add -A etc." But it doesn't take the file out of the index, and it literally can't take the file out of any existing commits that have it.
To remove a file from the index, without removing it from the work-tree, use git rm --cached.3
You not only have (or had) the file in the index—which means that git add -A updates it in the index—you also have it in some commit you have not yet pushed. So removing it from the index is not sufficient. You must abandon each commit that contains the large file.
To do so, you probably want to use git rebase -i to copy that commit (or those commits) to a new and improved version, where the improvement is simply "do not include the file in the commit".
See also Can't push to GitHub because of large file which I already deleted.
1The index is where you build the next commit. It is not a commit itself, but when you run git commit, Git packages up the index contents to make the new commit.
2The work-tree is simply the place where you work on your files, since the form of files inside Git's index and Git's commits is unusable for normal work.
3Note that you should not let the shell expand any glob patterns you are using in your .gitignore files, for two reasons. First, the shell expansion may not match that done by Git. Specifically, not all shells expand ** at all, and those that do, do not always do it the same way. Second, the work-tree contents may differ in significant ways from the index contents: for instance, if you have public/uploads/image/file/1 in the work-tree but not in the index, the shell, which looks at the work-tree, may include that in its glob expansion, while Git, which looks only at Git's index when doing git rm, would not put that in the list of files to remove—and as soon as Git finds one file it can't remove from the index, it stops removing other files.
git rm --cached -r /public/uploads/image/file/**
You have added the file to .gitignore after it was already added to git.
Look like your ignore pattern doesnot match the file pattern
public/uploads/image/file/30/show_55MiEk4_-_Imgur.gif
Add the following pattern to the .gitignore
/public/uploads/image/file/**/**
You first have to remove it and than push it again.
git rm --cached <file>
git commit -m "Message"
git push ....

git checkout master command gives error that a file would be overwritten

I just made tried to do git checkout master and I got this error:
macoss-MacBook-Pro-10:Marketing owner12$ git checkout master
error: The following untracked working tree files would be overwritten by checkout:
Marketing.xcodeproj/project.xcworkspace/xcuserdata/owner12.xcuserdatad/UserInterfaceState.xcuserstate
Please move or remove them before you can switch branches.
Aborting
but I am not sure how to handle this situation. I don't mind having this file overwritten by what is in the repo. What is the correct way for me to proceed here?
Thanks!
You have files that are not being tracked. Either
rm untracked.file1 untracked.file2
or
git add . && git commit -m "adding new previously untracked files that serve a purpose"
if you're having permission issues:
git add --ignore-errors .
Either delete the file if you don't care about it or stash it if you think you will need it in the future. Or simply rename.
Commit the files you want to keep and then do a git clean to remove the extra files you don't want to keep. This article on the git ready website describes it very well.
If you just want to get rid of one or two files in your working directory then you can do a dry run first and see which files would be cleaned up using:
git clean -n
And then when you are sure do this:
git clean -f
git clean has a -d switch if you want to clean up directories as well. And you can use that together with the other switches, so this is what I would normally use (and then after the dry run change -n to -f):
git clean -n -d
Then after your git clean, use:
git status
to make sure that you have no untracked files or uncommitted changes. And lastly switch to master with:
git checkout master

Exclude specific files when pushing to a specific Git repository

Is it possible to exclude specific files (*.ai, *.psd) when pushing to certain repositories with Git?
My need comes from trying to use Git for both version control and deployment to Heroku. If I include my graphic assets in the deploy, the slug size is larger than desired. However, I do need to include all project files in my main github repository.
The easy way to solve your actual problem is to create a .slugignore file in the root of the repository that lists files that shouldn't be packaged in the slug.
Heroku documentation on Slugignore
You can maintain a second branch for deployment to Heroku, which contains none of those files, but still merges from master. (Of course, you'll have to work out a system for resolving the merge conflicts you get when you modify the .ai and .psd files in master).
The specific thing you ask is impossible, for the simple reason that when you push, you transfer the exact commits from one repository to another, and two commits which don't have the same tree are by definition different commits.
Tip: The most recent versions of git have a --porcelain option for git status which will give easy to parse information like "M file1" "DU file2" (modified and unmerged/deleted by us, respectively). You could write a git-merge wrapper for your deployment branch which attempts the merge, and automatically cleans up the expected conflicts:
git checkout deploy
if ! git merge master; then
git rm $(git status --porcelain | awk '/^DU/ {print $NF}')
fi
(The reason I printed $NF instead of $2 is that if the file's renamed, it'll look like "DU original_name -> new_name", and the copy placed in the work tree will be new_name, not original_name.)
Of course, the script could get more complex if your situation is - you could look for only certain extensions (add them to the limiting awk pattern), or even capture the whole output in a perl script so you can easily do some more fancy logic...
There isn't a direct easy way to do that. It's certainly manageable, but with a lot of pain (git wasn't designed to do this).
It would be easier probably if you ask Heroku to provide a way to exclude some files from the deploy.

Resources