Github repo squash commits on master - github

I'm working with a github repo where a lot of commits historically have been "bugfix", "bugfix for real this time", "ok final bugfix", "finally fixed".
These were committed directly to master. How can I squash them?
Fromt his post a year ago - it basically sounds like this is bad, want to squash multiple commits in github. Has anything changed in the past year?

The answer today is basically the same: Squashing these commits is possible, but rewriting shared history is something to be strongly avoided in Git.
Imagine that you and I each have a copy of some repository that also exists on GitHub:
A---B---C
You notice that commits B and C should really have been committed together, so you squash these commits in your local copy. You now have
A---D
where D is a combination of B and C, while GitHub and I still have
A---B---C
At this point, even though the file content is the same everywhere, our commit IDs have diverged. Now you can't push to GitHub without --force, because GitHub's master branch contains two commits that are no longer present in your history.
If you do use --force you can make GitHub accept your changes, but now my repository contains commit objects that are no longer present upstream. I can't push to GitHub without using --force (which will invalidate your changes) or without doing a relatively funky merge to bring your changes in, probably rebasing my work, etc. And that's only possible if you communicate with me outside of Git to tell me what you've done.
This gets even messier with more developers (imaging doing this on the Linux kernel repository!) and with more work being done concurrently.
Really, any time you're tempted to git push --force, sit back and think for a moment. You're probably doing something that should only be done with an extremely good reason.
My recommendation is to accept that your history is a bit messy, but to try to improve things going forward. These commits can be cleaned up locally, before you push to GitHub (or share with other developers). Work in feature branches, use cherry-pick, rebase, etc. to clean up the commit history if necessary, then push.

Squashing is something which is used to merge a lot of commits into one. If you want to clean up last serval commit's check your last git log's by using
git log
this will look something like this
* df71a27 - (HEAD feature_x) Updated CSS for new elements (4 minutes ago)
* ba9dd9a - Added new elements to page design (15 minutes ago)
* f392171 - Added new feature X (1 day ago)
* d7322aa - (origin/feature_x) Proof of concept for feature X (3 days ago)
now if you want to squash last three commit's then
git rebase -i HEAD~3
by doing this you'll get into editor like this
pick f392171 Added new feature X
pick ba9dd9a Added new elements to page design
pick df71a27 Updated CSS for new elements
Edit the one who you want to squash like this
pick f392171 Added new feature X
squash ba9dd9a Added new elements to page design
squash df71a27 Updated CSS for new elements
When done, save and quit your editor. Git will now squash the commits into one. All done!

Related

Do squashed pull requests show up in the contributions graph as a single commit?

I'm working on feature branches that can have over a hundred commits over the course of a week or two. I've expected to get daily marks on my contribution graph for these daily commits once my pull request is accepted, but when that pull request gets "Squashed and merged", it looks like it just shows up as a single commit on the contribution graph.
Is this the intended behavior, or are my commits missing for a different reason?
Yes, this is the intended behavior. You only got one commit merged. That's the point of squash and merge.
I do not recommend squash merges. It takes all the carefully considered commit history about how the branch was developed and mashes it into a convenient but homogeneous paste.
I'm working on feature branches that can have over a hundred commits over the course of a week or two.
I would say this is the real problem. Feature branches should not regularly have over a hundred commits. Your features are too
big, or you're making a lot of commits to fix previous commits, or you have a lot of incidental merge commits from updating your branch, or all of the above.
Update your branch using rebase instead of merge. git rebase main rewrites your branch as if it were written on top of the latest version of main all along. This removes merge commits which say nothing but "I updated my branch" and makes it easier to see what work has been done on the branch. You can change git pull to do a rebase instead of a merge with git pull --rebase and by default by setting pull.rebase. See git-config and Git Branching - Rebasing.
Break up large features into a series of smaller features. This is a skill beyond the scope of this answer, but often a big change can be broken down into a series of smaller refactorings.
Eliminate incidental fixup commits. If you need to fix something in the previous commit, instead of making a new commit "amend" your changes to the previous one with git commit --amend.
For a general cleanup, do an interactive rebase and squash your incidental commits individually. Use fixup.
$ git rebase -i master
pick abcd1234 feature: do that thing
fixup 1234dcba whoops, had a typo in that thing
fixup b33fdead docs: document that thing
fixup afdcefff test: test that thing
fixup deadb33f fix that thing
pick efga1389 feature: did another thing
You had six commits, but you only really did two things. Now you will have just two commits for doing two things.
Using these techniques you can bring your PRs down to a handful of well thought out commits, each conveying important information to the reviewer and future developers wondering why the code was written that way.
See Rewriting History for more.
Yes, they show up as a single commit. That's because GitHub only counts commits that end up on the default branch, and when you squash a PR, you end up with one commit on the default branch.
I personally don't worry about my contribution graph, so this doesn't matter to me. However, I also don't use squash and merge, since I write nice, bisectable commits with good commit messages, and squash and merge destroys that. If it's important to you not to reduce the work that a contributor has made down to a single commit, then you would need a merge strategy whose goal isn't explicitly to destroy history.

Eclipse Git - Making changes at the same time

This is probably a noob question, as I only started using Eclipse Git a few days ago.
I was wondering if it was, in any way, possible to have multiple people working on different files in a repository but, when ready to commit, only have one commit for all, instead of one commit per person...?
I was also wondering if there was an option to automatically pull modified files, or a way to update the modified files in every person working in the repository, without making a commit per person first?
I'm asking this because I use Jenkins, and every time a commit is made in GitHub, it immediately starts a build, and it would be very annoying to create a commit per person just because of probably some lines of codes.
Best regards
EGit doesn't have a feature for that, but you can work around it by "squashing" the commits in GitHub. Here's how it works:
Step 1) Create a branch
Step 2) Make everyone work on that branch until it's time to commit (in your words)
Step 3) Create a pull request for merging the branch with master or whatever branch that is marked as default
Step 4) Click "Merge pull request" and then do this:
If you can't find the option to squash-merge, go to the repository settings and make sure the checkbox highlighted in this image is full:
Step 5) Confirm squash and merge

Hg: Find out if a branch has been merged in to default?

So I've got a long and detailed Mercurial Repository which has been worked on by several times over a long period of time with lots of branches, in that time no one knew that you can close a branch.
Recently I've closed nearly 1200 abandoned heads and it runs a lot better. However we have a number of branches which we want to preserve. Some I think may have already been merged back in to default but I'm not sure.
I can see if I run hg branches that they are marked as (inactive) meaning that it has been merged in to another branch but on checking its not merged directly back in to default. Is there a way I can check if somewhere these branches have been merged back in to default even if its via another branch ?
I believe you can accomplish that with revsets, in particular:
hg log -r "not ancestors(heads(default)) and head() and not closed()"
That should get you all heads of named branches that have not been closed and are not ancestors of (i.e. have not been merged into) the default branch.

GitHub: restore old commits

I am working with the GitHub GUI on Windows.
I did some work on my project which was successfully committed about a month ago going forward. Unfortunately other person who also works on this project recently committed the files I changed without realizing that he removed a huge portion of my work.
Now my question would be: is there an easy way of restoring my commits. This is not one commit. For the past month I made several very important commits to the project which got killed by the other party error.
I really don't want to go thru each file individually and re-aaply the changes manually, especially since I already got paid for that work.
How can I get my commits back?
IF you don't see your commit anymore in the history of the repo, that would mean the other developer has done a forced push (git push --force).
In that case, use git reflog (as in this answer) to find your commits back.
If yo do see your commits, then you could revert (git revert) the commits introduced by the other developers in order to cancel them, which should leave your branch in a state reflecting your work.
In both cases, this is a communication issue: you need to coordinate with the other developer in order for both of you to agree on a state from which to move forward.

github branching and merging

I'm relatively new to github (I've pushed my rails app to a repo and I push it up regularly to keep it updated, with a 'commit' message, which is very handy to see where I am) and I just want to check I'm about to do the next stage correctly, without messing it all up.
Some history: a few months ago a software development company sent me the source code of the project, which I tasked them to do. It's called Project_v_1. Over the months I've been making css/javascript/html changes - models and controllers not for me yet!
But I have done a substantial amount of work and, as I said, I update it regularly. Project_v_1 is the master branch (the only branch in the repo, in fact)
Now I'm about to receive Project_v_2 from the software company. I want to put the best of my changes I made to Project_v_1 into Project_v_2. Do I have to manually seek out the changes in the files I made and copy/paste them into P_v_2?
Or can I do something like:
create a new branch in my repo: P_v_2
put P_v_2 into that branch.
merge P_v_2 and my master (P_v_1).
Am I scr**ed? It just seems a bit miraculous to think there's a simple resolution to my problem.
Thanks,
C
git merge will merge every commit in v1 to v2. I suggest you to use cherry-pick which is useful to apply same commits between branches :
Checkout the v2 branch and git cherry-pick <your-best-commit-id>