Git Squash and remove previous commits - git-commit

Maybe I misunderstood how GIT works.
I've run git rebase -i HEAD~10 and I could squash 10 commits into one. The issue is that all squashed commits are still there, and I thought they were going to be dropped after merging them all into one.
Is this the expected result? If so, can I rewrite the history to remove useless commits (since these changes are already in the commit which all previous commits were squashed)?

When you began your interactive rebase session, you should have been prompted with a list of the last 10 commits from the current branch:
git rebase -i HEAD~10
pick as2i8dw first commit
pick ee361eb second commit
...
pick b2762sx most recent commit
You need to change this file to the following:
pick as2i8dw first commit
squash ee361eb second commit
...
squash b2762sx most recent commit
Then you need to do a git commit to save the changes. Now when doing a git log you should only see the as2i8dw commit and none of the other ten.
That being said, is this what you did?

The issue is that all squashed commits are still there
If those commits are still accessible by any other reference (other branch or tag), there would still be visible, even after the current branch is rebased.
Try instead squashing the commits with a git reset --soft.
If HEAD does still reference your 10 commits:
git reset --soft HEAD~10
git commit -m "squashed 10 commits"

I faced the similar issue and figured out the actual cause for it:
The flow:
git rebase -i HEAD~10
# Retain the first commit from below( as pick) and change the rest of the `pick` to `squash`
# After your rebase is successful
git log
# You can see all your commits squashes to one commit
Then now when you git pull from your remote branch, it will pull the rest of the commits which is not there in local ( basically all the commits you had squashed previously, since it is now present in one commit) and hence you are seeing the previous commits as well.
Better way is to git push -f to your remote branch, if you are confident that you have no new changes added there.
P.S: If you have any new changes in the remote branch, better to:
git rebase origin remote_branch
and then squash your commits.

Related

Bitbucket deleting commits

I have a problem, I've committed some code and now I want to delete this commit, but this is not the last commit in whole project.
I want to delete whole blue branch( if its possible).
if you want to remove the commit use
git rebase -interactive
and
git filter-branch
But you'll have to recommit every commit which goes after the commit you want to delete.
Or if you just want to remove the changes of the specific commit will be better to use
git revert <hash of the commit>
If you want to delete the whole branch, Click the branches icon on the left side of bit bucket, it will display all the branches. There will be columns like branch, Behind/Ahead, Updated, pull req, build, Actions. Click 3 dots in action column for your branch-> choose delete branch. Keep a backup in local before deleting.
I recommended removing the selected commits. use this
git reset --soft <commit ID>
For example
git reset --soft 23wfee 3eelw2 34efff
Then your particular commit will remove but if you don't want that commit changes then use hard instead of soft like this.
git reset --hard <commit ID>
Solve the problem with git rebase -i id of last right commit, then you can delete commits that you don't want to see , then git push -f origin master

Using git pull properly

I am new to git so please bear with me. I have a rails application on my local machine that I am experimenting with and pushing to the master branch periodically. It works at the moment, but I have fallen behind, and now I am many commits behind the master.
$ git branch
* master
$ git status
On branch master
Your branch is behind 'origin/master' by 27 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean
However, when I use git pull and then start rails, my application breaks with a precompiler error. So I am forced to use git --reset to go back to the local commit before I used git pull.
What is the right way to get around this issue and merge with the latest changes on the master branch? Would one use git --rebase in this case?
Try
git stash
git pull origin master
And once it updates, git stash apply to reapply your local changes
Since nobody has stated this clearly yet: You ask
What is the right way to get around this issue and merge with the latest changes on the master branch?
When you do git pull that does merge the remote changes into your current branch. Whether you would choose to do a rebase instead of a merge (per your other question) is a separate issue, but the default behavior is to combine the two sets of changes (local and remote).
More precisely, by default git pull does a fetch followed by a merge. The exact merge operation depends on configuration and on command-line options, but in a typical configuration where origin/master is upstream of master, saying
git pull
will merge origin/master into master.
So why the errors?
One possibility is that there were merge conflicts. If that happens, git will tell you. If you say git status in this condition, it will tell you that there's a merge in progress and it will indicate which paths (files) need conflict resolution.
Another possibility is that the changes don't conflict (in that they don't affect the same region of the same file) but still don't work properly together. That you would simply have to debug.

Git: force push cleared all of my commits - can I get them back?

My live site was updated since my last commit, and I hadn't made any local changes, so I wanted to just push everything that's live up to my Git repo.
So I did a git push --force
Now I have no commits in my repo, other than the most recent commit.
How can I get them back?
Here's the repo if you need the link: https://bitbucket.org/nicolefurlan/us-vegweek-2014
I'm not sure which repo was pushed to where, but on any repo (local or remote) you can run git reflog to get the history of all previous commit states in that repo.
Use git reset --hard <commit-id> to restore the last good commit to master.
If your last good state wasn't committed at any point in time, there's no way to retrieve it.

Rails rollback deploy AND master to ref while preserving failure in new branch

I have run into trouble with a recent production (well, staging actually but we'll keep calling it 'production') deployment.
I'd like to (read: need to) roll back the deploy to a previous commit. Actually, I'd like to go back a ways and then move forward cap deploying each commit one by one until I see the problem materialize. I know I can use cap -S revision=8c9ffa787b22cff019b27f71194637aa85506f9c deploy to deploy a specific commit.
My question is, when I FIND the commit I want to stick with how can I reset HEAD and master, etc. so that basically, master points to that commit and, ideally, all the subsequent commits are captured in a new branch of some name, say rabbithole?
Need to do this w/out fouling the git repos in development, GitHub and then the cached-copy that Capistrano automatically creates on production server.
Hope I'm making sense. If not please ask for more information.
Thanks!
I'd say you want to revert all commits between you stable commit and you HEAD. Check this
git checkout master
git revert XXSHAXX..HEAD
Where XXSHAXX is your stable commit.
This will create a bunch of new commits - one for each after stable. As a result you'll have a new commit equivalent to you stable in HEAD and none of your history will be lost.
P.S. and you wont be beaten by others who works in same repo.
To rollback to a previous commit
cap deploy:rollback
To rollback to a previously deployed commit
cap deploy:rollback:code
Once you've found a commit that you want to keep at master, you can do a rebase. Not sure if this is the best route, as you should always be wary of forcing an update on master.
I would temporarily change the branch where my staging environment is pulling from, rather than push a forced update on master upstream.
Ok, warnings aside:
$ git checkout master; git checkout -b master-backup-before-rebase; git checkout master
There might be a quicker/simpler way to do this, but we basically ensure we're on master, create a new branch called master-backup-before-rebase, and then go back to master.
$ git rebase -i head~XXX
Replace ~XXX with however many commits back you want to remove + 1.
Next, a text editor window will open - remove the lines of all commits you want to delete. Save, and close the window.
$ git push origin master -f
Voila.
Be very careful with this, and ensure that your backup branch exists before rebasing, lest you accidentally remain on the Master branch because you had uncommitted local changes or something.

Git checkout <SHA> and Heroku

I created a local Git repo on my laptop and then pushed the source to Heroku creating a remote branch. After a few days of commits and pushes, I need to rollback to an earlier commit. Here's what I did.
cd <app root>
git checkout 35fbd894eef3e114c814cc3c7ac7bb50b28f6b73
Someone told me that doing the checkout created a new working tree and not the branch itself, so when I pushed the rollback changes to Heroku, it said everything is up to date and nothing was pushed. How do I fix this situation? Thanks for your help in advance.
When you checkout a direct commit name (using the SHA-1 hash of the commit object) instead of checking out a branch name, you end up with a “detached HEAD”. HEAD is the “ref” that keeps track of what is currently checked out. It becomes detached when you directly checkout a commit instead of a branch (it is not attached to any branch). No branches are updated when you detach a repository's HEAD. You might think of the detached head state as if you had an anonymous branch checked out.
To reattach your repository's HEAD, you will want to save the current HEAD as a branch and check that branch out:
To save the current HEAD in a new branch do this:
git branch <new-branch-name>
To overwrite an existing branch you need to use --force:
git branch --force <existing-branch-name>
Then, reattach your repository's HEAD by checking out the new/updated branch:
git checkout <branch-name>
(where <branch-name> is the same as <new-branch-name> or <existing-branch-name>, depending on which of the above two commands you used)
This sequence (git branch to make a ref point to the current HEAD commit, then git checkout that updated branch) will carry forward any uncommitted content that you might have in your working index and/or tree.
In the future, if you want to ‘roll back’ the current branch to some previous commit, you should use this instead of detaching your repository's HEAD:
git reset --hard <commit>
This will reset the current branch (or your detached HEAD, if it is already detached) to the named commit, and make the index and the working tree reflect that commit (i.e. it throws away any commits since the specified commit along with any uncommitted content).
The detached HEAD state is useful for revisiting old states, and sometimes for short-term work that you are not sure you will keep. Other than that you probably want to avoid it.
You want to reset:
git reset --hard 35fbd894eef3e114c814cc3c7ac7bb50b28f6b73

Resources