News for hackers. Stuff that matters.
Re:Write good git commit messages by scrollaway on Wednesday December 12, 2018 @07:50AM (#18663431)
Writing good commit messages is one of those things that IMO make the difference between a dev who produces good code, and a dev who produces high quality work in general.

The git log is one of the main entry points to an open source (or closed source, in fact) project. Following them tells a story, and can help you understand decisions made.

Imagine you have two projects to bisect. One of them has clean, atomic and descriptive commits. The other has a git log that looks like this: https://github.com/pypa/pipenv/commits/master?after=d4d54eeb...

I know which one I'd want to debug. This is also the primary reason why I highly dislike merge commits: They make git logs extremely unreadable.

The thing is that writing clean commits is something that is extremely easy to do. Unlike docs and tests, it's not more work (it's less, in fact) and it's not something to continuously maintain as the code changes. It's an immediate improvement you can make to your development habits that will have a consequential improvement to your QOL. You will catch bugs doing this!

(Tip when writing atomic commits: Use `git add -p`. That lets you stage patch hunks.)

Re:Write good git commit messages by sly010 on Wednesday December 12, 2018 @09:23AM (#18664091)
Writing the good quality commit message is not that hard and is sometimes actually enjoyable (after all i get to brag about this feature / bugfix / solution).

What does cause a lot of mental overhead (and consider myself a decent engineer) is creating commits that have a single purpose in the first place.

Working on a new feature I often have to refactor something, and while I am at it, I clean up some related parts. That is at the minimum 3 commits applied in the correct order, sometimes over different branches. At that point there is a lot of `git add -p` and `git stash apply` going on, which takes considerably more mental energy while you see some colleagues getting away with `git commit -a`.

Writing good commit messages itself is the reward for creating good commits.

Re:Write good git commit messages by gregmac on Wednesday December 12, 2018 @03:48PM (#18667616)
This is why I work in graphical clients (GitKracken being my current preference). They make interactive staging of individual files or lines utterly trivial.

I do partial commits significantly more often than committing everything, and often do things like a couple commits, checkout another branch (and GitKracken does an auto stash + apply) then commit a separate fix there before switching back to the original branch.

Also there are several other things it makes easier: being able to multi-select commits and see a combined diff, quicky diff between two random branches, and just generally browsing back through history. And importantly, it's easy to do all this without having to remember, copy/paste or type any branch names or commit hashes.

Re:Write good git commit messages by gdfasfklshg4 on Thursday December 13, 2018 @04:11AM (#18670952)
Just an FYI if you ever lack access to GitKraken Git gui does line by line staging. It is not as pretty but it works well.
Re:Write good git commit messages by gregmac on Thursday December 13, 2018 @11:33AM (#18673591)
I'd say it's also not as functional. With a GUI you can click around and browse through other files, as well as stage/unstage with the same interface.

With the CLI, all you can do is cycle through "Stage this hunk [y,n,q,a,d,e,?]?" prompts, and if you mess up, you have to exit completely and do `git reset --patch` and cycle through those prompts again (at least, I don't know another way to do that). Actually it's a bit worse because it has even more options:

    Unstage this hunk [y,n,q,a,d,j,J,g,/,s,e,?]? ?
    y - unstage this hunk
    n - do not unstage this hunk
    q - quit; do not unstage this hunk or any of the remaining ones
    a - unstage this hunk and all later hunks in the file
    d - do not unstage this hunk or any of the later hunks in the file
    g - select a hunk to go to
    / - search for a hunk matching the given regex
    j - leave this hunk undecided, see next undecided hunk
    J - leave this hunk undecided, see next hunk
    s - split the current hunk into smaller hunks
    e - manually edit the current hunk
    ? - print help
If you use this all the time and get used to the commands, and are also good at picturing the separate pieces you are trying to commit in your head, it's probably fully functional.

If you're like me, and come back to your code after an unrelated 1hr meeting (or lunch) and are trying to sort out the 3 or 4 separate changes you did earlier in the day to make nice logical commits... good luck.

Re:Write good git commit messages by u801e on Thursday December 13, 2018 @02:22PM (#18675158)
> With the CLI, all you can do is cycle through "Stage this hunk [y,n,q,a,d,e,?]?" prompts, and if you mess up, you have to exit completely and do `git reset --patch` and cycle through those prompts again (at least, I don't know another way to do that). Actually it's a bit worse because it has even more options ...

You can get a hybrid of the two if you use commands like recountdiff (from patchutils) and git-apply --cached. I do this by reading the output of git diff into vim, editing diff hunks and running recountdiff on those hunks, and running git-apply --cached. If I mess up, I can always read the output of git diff --cached and run git-apply -R --cached to unstage that hunk.

I find it better than using the CLI menu driven tool that you refer to.

Re:Write good git commit messages by gdfasfklshg4 on Thursday December 13, 2018 @12:07PM (#18673911)
Git gui is a GUI that is part of the core git product...
Re:Write good git commit messages by gregmac on Thursday December 13, 2018 @01:44PM (#18674845)
Oh! Wow, sorry, I didn't even know that existed (run `git gui` to view). Thanks!

And you're right: it's completely functional for doing partial commits, but I agree definitely not as pretty.

Re:Write good git commit messages by awolf on Wednesday December 12, 2018 @11:07AM (#18665023)
Rather than `git add -p`, I suggest creating a second clone of your repo, staging your foundational refactor changes in the second repo, creating and merging your commits there, and then rebasing your working branch.

This makes sure you can fully test your refractors and that their change sets stand alone.

Re:Write good git commit messages by dllthomas on Wednesday December 12, 2018 @12:12PM (#18665644)
If you know your way around git well enough that you're not going to be screwing up repository state in ways you can't fix, there's no reason to operate from separate clones - check out git worktrees :)
Re:Write good git commit messages by bacon_waffle on Wednesday December 12, 2018 @02:44PM (#18667096)
Thanks for that! I've occasionally thought a feature like this would be possible and helpful, but hadn't encountered it until your mention.
Re:Write good git commit messages by dllthomas on Wednesday December 12, 2018 @08:23PM (#18669173)
I felt the same way when I stumbled across it in a man page :)
Re:Write good git commit messages by CGamesPlay on Wednesday December 12, 2018 @02:42PM (#18667080)
I use long-running git rebase -i with a line like “x false” to pause the rebase, run tests or finish packaging the refactor, then git rebase --continue.
Re:Write good git commit messages by invalidOrTaken on Wednesday December 12, 2018 @12:50PM (#18666000)
YES. It's very easy to write good commit messages; what's much harder is making "good" (as in: atomic, understandable) commits. I know I'm just restating what you said, but...I just agree very strongly.
Re:Write good git commit messages by gregmac on Wednesday December 12, 2018 @05:04PM (#18668146)
Part of the problem is it's not obvious why you need to do this until you need it, at which point it's too late.

Reasons include: understanding how a change works (all related code in one place without extra distraction), easy to revert, easy to figure out why that code is there during a blame.

Re:Write good git commit messages by u801e on Thursday December 13, 2018 @02:19PM (#18675131)
> What does cause a lot of mental overhead (and consider myself a decent engineer) is creating commits that have a single purpose in the first place.

That's why I typically write code where I implement a feature and then go through the diff to determine what to stage and what goes into each commit. Trying to do this while implementing something isn't really something that's worthwhile.

Re:Write good git commit messages by notyourwork on Wednesday December 12, 2018 @11:06AM (#18665013)
> What does cause a lot of mental overhead (and consider myself a decent engineer) is creating commits that have a single purpose in the first place.

I agree, this is what demonstrates maturity in an engineer. Perhaps we need to focus on commit driven development.

I personally do not allow teammates to ship macro commits covering multiple features. I call this out in code review process.

Re:Write good git commit messages by pkamb on Thursday December 13, 2018 @08:22PM (#18677652)
Staging individual lines and hunks is unbelievably easy with a good git GUI. I don't know how people work without one.
Re:Write good git commit messages by duxup on Wednesday December 12, 2018 @09:17AM (#18664041)
Before I recently started coding I used to be a network engineer. I worked with a LARGE team at my previous job so documentation was CRITICAL for working difficult technical issues / documenting troubleshooting / changes / etc. If you don't document what you did, what it does, and why, everything goes to hell fast (sadly some places operate like that). So for me it came naturally that you're responsible for documenting what you do as much as what you do.

Working my current coding job I'm by no means the fastest coder, or the best, but man I get praise for documentation, comments, commit details. It kinda amazes me how many skills that are just straight required in one field, earn heaps of praise in others.

Re:Write good git commit messages by jrm2k6 on Wednesday December 12, 2018 @12:13PM (#18665654)
Being thorough and highly detailed is definitely something that I praise with the colleagues I have doing it well. Someone taking time to write good PRs and maintaining documentation is definitely more useful in my book that a fast coder. Good documentation reduces the bus factor by a lot, and make someone a team player in my opinion.
Re:Write good git commit messages by gdfasfklshg4 on Wednesday December 12, 2018 @09:05AM (#18663955)
> This is also the primary reason why I highly dislike merge commits: They make git logs extremely unreadable.

I really really disagree. If the branch has one logical commit then no merge commit is needed. Otherwise the merge commit shows what happened and more importantly that these N commits came into the mainline as a single change.

Re:Write good git commit messages by scrollaway on Wednesday December 12, 2018 @09:25AM (#18664105)
So tell me, this is readable for you?

https://imgur.com/GCWsFwU

And I'm not cherry-picking... I usually see much, much worse git logs than this from merge-commit users. In fact, if I scroll down, this is what it looks like:

https://imgur.com/a/nQXWa4Q

Edit: For a point of comparison, here's one of my projects using atomic commits and rebases:

https://imgur.com/a/vTZ5qxT

Re:Write good git commit messages by gdfasfklshg4 on Wednesday December 12, 2018 @10:33AM (#18664718)
The first example does not rebase first...

My projects also have a linear progression. They look like...

    *     -- Bugfix
    *     -- Feature B
    | \
    | *   -- Implement some other logical part of feature B
    | *   -- Implement first logical part feature B
    | /
    *     -- Feature A
Re:Write good git commit messages by MayeulC on Wednesday December 12, 2018 @04:38PM (#18667979)
I am curious as to why this is downvoted? This can be a valid answer to the parent's concern.
Re:Write good git commit messages by monsieurbanana on Wednesday December 12, 2018 @09:33AM (#18664177)
Let me fix this for you...

git log --first-parent

With that switch and writing correct merge-commit messages you get the best of both approaches.

Re:Write good git commit messages by scrollaway on Wednesday December 12, 2018 @09:35AM (#18664195)
"And correct merge-commit messages" -- I've NEVER seen those. In 99.99999% of projects, this is what you'll get:

https://imgur.com/a/4f6Hw2w

Re:Write good git commit messages by monsieurbanana on Wednesday December 12, 2018 @09:42AM (#18664269)
You're moving goalposts. Yes almost nobody changes the default merge-commit message. But that's because, like you, they don't know about --first-parent (or they just don't care about commit history)

That doesn't mean using merge-commits is wrong, that means people write bad commit messages, which you already complained about.

Re:Write good git commit messages by scrollaway on Wednesday December 12, 2018 @09:49AM (#18664336)
… am I moving goalposts? I do know about --first-parent and it is not intended to be a feature to make git logs readable. It gets rid of nearly the entire git history. At this point, you might as well simply go to the github page and look at merged PRs; that will actually get you something readable.

I fear you may be terribly misunderstanding the point of atomic commits and readable commit messages. Everything within a merge commit will still come up during a bisect, for example. If the commits are non-atomic and/or they are badly written, that is still an issue.

--first-parent hides the problem, and adds a new one. I'm not sure what your thinking is. Once again, what's more readable to you of all the screenshots I linked?

Re:Write good git commit messages by btschaegg on Wednesday December 12, 2018 @03:45PM (#18667593)
Not to argue in either direction, but I think you should be able to "fix" the bisect problem with a script like this:

  #!/bin/bash
  bad=$(git rev-parse "$1")
  good=$(git rev-parse "${@:2}")
  
  git bisect start "$bad" $good
  
  filter=$(echo "$good" | sed 's/^/^/' | cat <(echo "$bad") - | xargs)
  comm -13 \
      <(git rev-list --first-parent $filter | sort) \
      <(git rev-list                $filter | sort) \
      | xargs git bisect skip
I haven't tested it all too thoroughly, but from what `git bisect view` tells me, this seems to work like a `git bisect --first-parent`. I'm wondering why there is no such option...

For anyone unfamiliar with git extension scripts: You should be able to put it in an executable (`chmod +x`) file (say `git-bisect-branch`) in your $PATH to make it usable (`git bisect-branch $bad $good...`).

Re:Write good git commit messages by gdfasfklshg4 on Thursday December 13, 2018 @06:08AM (#18671423)
Good branch names end up in the default commit by default...
Re:Write good git commit messages by mkesper on Wednesday December 12, 2018 @12:19PM (#18665699)
You'd want to use a repo that only allows fast-forward and rebase everything that would be a merge. We use Gerrit for that.
Re:Write good git commit messages by scrollaway on Wednesday December 12, 2018 @12:36PM (#18665864)
Yup, that's what I'm arguing in favour of. I systematically disable merge commits on every repo I manage.

I suspect that if merge-commits hadnt been the default on github since forever, it wouldnt have so many proponents.

Re:Write good git commit messages by gdfasfklshg4 on Thursday December 13, 2018 @05:10AM (#18671194)
> I systematically disable merge commits on every repo I manage.

Do you have buy in from other team members for this?

Also what do you do if master needs to be merged back into develop? Do you really rebase develop and make everyone fiddle with all their feature branches?

Re:Write good git commit messages by scrollaway on Thursday December 13, 2018 @10:05AM (#18672754)
There is no develop, master is continuously deployed. Users can create feature branches and PR them but there is just no merge commit, they are pulled in fast-forward. In projects where I need stable releases, I create stable/1.2.x type branches off of master at a point in time. I cherry-pick commits onto it after the first release if there are subsequent ones.

You can see this in action here:

https://github.com/dj-stripe/dj-stripe/commits/master

https://github.com/dj-stripe/dj-stripe/commits/stable/1.2

Re:Write good git commit messages by u801e on Thursday December 13, 2018 @02:36PM (#18675265)
Though fast forward merge commits (where the referenced tree is the same as referenced by the second parent) can be useful because they provide a way for you to group related commits for a feature together (git log merge_commit^..merge_commit^2). There are features that require more than a single commit to implement.
Re:Write good git commit messages by vsl on Thursday December 13, 2018 @08:45AM (#18672238)
Let me this fix for you too: don’t merge master into featur branches. What kind of insanity is that?
Re:Write good git commit messages by lysp on Wednesday December 12, 2018 @07:37PM (#18668948)
I go one step further - All changes (even single commits) are in a feature branch.

Feature branch is prefixed with issue number. eg. PROJ-1234-update-ui-to-do-something. That ensures that every commit is logged against an issue.

If you list --first-parent and show the list of merge commits, you see a list of features which were implemented into the dev branch.

If you need to drill down into lower level changes of a feature, you can look at the individual commits that were made in that branch.

That way merge commits are atomic commits of features, and commits in a branch are logical commits/steps for an individual feature.

And in answer to the original post - I try to make all commits have a message of what was the type of change, what the change was, and where it was. eg. "Added a clear button to reset all form elements on the update address page". The general rule is, you should be able to read the commit message and know exactly what was changed and where. Compared to "Added clear button".

Re:Write good git commit messages by maelkum on Friday December 14, 2018 @08:28AM (#18680623)
I am using this method to a great success at my current job. It leads to always having a clear, well-defined place where you look for changes related to issue XYZ.

Support from tooling also helps a lot, e.g. "checkout branch of issue XYZ".

Re:Write good git commit messages by scrollaway on Thursday December 13, 2018 @02:40AM (#18670529)
This is IMO a potentially good system but it requires a lot of rigor. In my experience, such systems break down unless they are rigidly enforced, and that's never fun for anybody.
Re:Write good git commit messages by lysp on Sunday December 16, 2018 @01:16AM (#18691992)
The way I have set it up is to do 2 things:

1) Create a post-commit hook script that only allows commits into feature branches.

This prevents accidentally committing into the dev/master branches (it still allows merges).

2) Create a script file that all developers use to start / end features which handles all the branch creation, pushing and pulling. That way the process is standardised and you cant make a mistake.

eg.

* script startfeature abc123-this-is-new-feature

* script endfeature (this automatically picks up local open features)

The only time there is ever an issue is when the end-feature causes a conflict. This is solved by rebasing your local branch, fixing up any issues in your commmits and then ending it again.

Re:Write good git commit messages by adtac on Wednesday December 12, 2018 @09:20AM (#18664056)
I fail to see how that would be useful. Commits are supposed to be atomic, self-contained changes by themselves. More often than not, I see merge commits only when people abuse commits for temporary state of work (with useless commit messages like "fix" and "temp"). Instead, if each commit did one thing and one thing only, why would you need a visual indicator that these set of commits came from a particular branch?
Re:Write good git commit messages by jonahx on Wednesday December 12, 2018 @09:52AM (#18664358)
Because they are logically grouped and that grouping is often more important than the commits themselves -- together, they accomplish a higher-level goal.

You want both that goal and the individual tasks which achieved it to be visible.

Re:Write good git commit messages by adtac on Wednesday December 12, 2018 @09:56AM (#18664400)
That information can and should be a part of the commit body. An extra commit just for that information is, in my opinion, a hack and a workaround.

I guess we have fundamental differences on how a tree should be structured. It's more of a DAG in your case, but I prefer to keep a tree a tree.

Re:Write good git commit messages by jonahx on Wednesday December 12, 2018 @11:27AM (#18665214)
Not sure I follow your argument. How would you put information about the semantic meaning of a series of commits into "the commit body"?

The only point I'm making essentially is that "the commit" is too granular to capture all the information you need about your work and its history. You need some kind of grouping mechanism as well. It doesn't have to be merge commits, necessarily. But as I understood it, your original argument was that "there is no need for anything higher level than a commit." But there clearly is imo.

Re:Write good git commit messages by Thiez on Wednesday December 12, 2018 @01:51PM (#18666611)
If you tag HEAD after each merged PR you can still see which commits belong together, they'll be between two tags.
Re:Write good git commit messages by jonahx on Wednesday December 12, 2018 @02:36PM (#18667022)
Yeah, when I said:

> It doesn't have to be merge commits, necessarily.

I was thinking of a tagging strategy.

Re:Write good git commit messages by tome on Wednesday December 12, 2018 @11:12AM (#18665080)
> (Tip when writing atomic commits: Use `git add -p`. That lets you stage patch hunks.)

Even better, use `git commit -p` and skip the staging area entirely.

Re:Write good git commit messages by u801e on Thursday December 13, 2018 @02:38PM (#18675283)
> Even better, use `git commit -p` and skip the staging area entirely.

If you end up staging the wrong hunk, then you will have to reset and recommit. With git add -p, you would only need to reset the hunk.

Re:Write good git commit messages by tome on Monday December 17, 2018 @06:44AM (#18698354)
You indeed have to recommit everything (which I prefer) but you don't have to reset anything (since nothing is in the staging area).
Re:Write good git commit messages by u801e on Tuesday December 18, 2018 @09:12PM (#18712466)
>> If you end up staging the wrong hunk, then you will have to reset and recommit

> you don't have to reset anything

You have to reset the branch pointer to the previous commit, but I think using the --amend switch may do that for you.

Re:Write good git commit messages by tome on Wednesday December 19, 2018 @06:57AM (#18715024)
If you exit the commit message editor so that it retuns a non-zero exit code to git then nothing is committed and nothing is staged.
Re:Write good git commit messages by dllthomas on Friday December 21, 2018 @01:27PM (#18735340)
With git, usually (maybe always?) exiting having saved an empty buffer is equivalent.
Re:Write good git commit messages by rakoo on Wednesday December 12, 2018 @11:15AM (#18665105)
> The other has a git log that looks like this

That's because, like GitHub itself, the documentation for them is not in the commit messages but in the pull-requests. Look at their PR page (https://github.com/pypa/pipenv/pulls) and individual PRs, you'll see that it's much better organized.

The difference is that now the source of truth is not git itself, but wherever the pull-requests are.

Re:Write good git commit messages by ajmurmann on Wednesday December 12, 2018 @11:21AM (#18665167)
That really ruins a lot of tooling. Going back through history to see when a bug might have been introduced; doing git blame to find out why a line of code is like it is... If you write his commit messages, you also get good PR messages for free.
Re:Write good git commit messages by ajross on Wednesday December 12, 2018 @11:30AM (#18665233)
> the source of truth is not git itself, but wherever the pull-requests are.

And you think storing that source of truth separately from the code is... a good thing?

Re:Write good git commit messages by rakoo on Wednesday December 12, 2018 @04:25PM (#18667894)
I personally don't, that was just a way to explain the whys. But this whole thing is probably a good reason to ask whether staying in git, the completely decentralized VCS, to work in a centralized manner, is the best way to go. As the sibling comment evocated, our traditional tooling is limited in that way of working but that doesn't mean it's inherently bad; maybe we need new tools?
Re:Write good git commit messages by atq2119 on Wednesday December 12, 2018 @10:24AM (#18664626)
> (Tip when writing atomic commits: Use `git add -p`. That lets you stage patch hunks.)

Also take a look at `git gui`, which is part of Git core.

Re:Write good git commit messages by wpietri on Wednesday December 12, 2018 @09:27AM (#18664120)
When I clicked on that link, I was totally prepared to say, "Well that's not that bad." But wow, that's bad. If I were looking at getting involved, that could be enough to stop me. And all those broken builds might be enough to keep me from using the project at all.
Re:Write good git commit messages by scrollaway on Wednesday December 12, 2018 @09:37AM (#18664215)
Yeah the awful git log is one of the things that turned me off contributing to pipenv. They got better at it, FWIW.
Re:Write good git commit messages by abhishekjha on Wednesday December 12, 2018 @08:53AM (#18663870)
>This is also the primary reason why I highly dislike merge commits: They make git logs extremely unreadable.

I am new to git. You will have to merge eventually with somebody when you are collaborating. Can you really avoid merge commits?

I don't like how `git reflog` keeps track of which hash did I switch to. I only jump to hashes for a quick run. I don't want it actually tracking that in the log. Does anybody know how to avoid that as well?

Re:Write good git commit messages by nordsieck on Wednesday December 12, 2018 @08:57AM (#18663903)
>> This is also the primary reason why I highly dislike merge commits: They make git logs extremely unreadable.

> I am new to git. You will have to merge eventually with somebody when you are collaborating. Can you really avoid merge commits?

Many developers prefer to only rebase, such that master looks like a single chain of commits without any branching or other administrative structure.

Re:Write good git commit messages by aviraldg on Wednesday December 12, 2018 @08:57AM (#18663896)
Yes, you can rebase: https://www.atlassian.com/git/tutorials/merging-vs-rebasing

(best used with --ff-only in your config to avoid unnecessary/unintentional merge commits)

Re:Write good git commit messages by drums8787 on Wednesday December 12, 2018 @05:10PM (#18668183)
Agree, learn to rebase well. Having a chain of atomic, well commented commits is bliss.
Re:Write good git commit messages by rocqua on Wednesday December 12, 2018 @08:52AM (#18663868)
I've had something like `git add -p` in my mind for a while now, thanks for pointing me in the right direction!

It was one of the few things left in git where I prefered IDE's over the plain command line.

Re:Write good git commit messages by jgtrosh on Wednesday December 12, 2018 @09:22AM (#18664074)
> (Tip when writing atomic commits: Use `git add -p`. That lets you stage patch hunks.)

Tip when using patch modes: spend time learning edit mode, and IMO avoid edit mode for checkout or reset patch modes.

Re:Write good git commit messages by BerislavLopac on Wednesday December 12, 2018 @10:22AM (#18664613)
The trick I've developed to improve my commit messages is to ask my self how would I explain something to do what the commit does, in a widest sense. Before that my messages either amounted to "HAAAAANDS" (https://xkcd.com/1296/ -- there is always an appropriate XKCD), or tended to go into minutiae of implementation ("added a boolean attribute 'foo' and changed method 'bar' to raise FooBarBazException when the calculated value is 42"). The "instructions" approach helps me focus on why something was done ("implement verification of the IMO field") than how (which should generally be obvious from the code itself).
Re:Write good git commit messages by krispbyte on Wednesday December 12, 2018 @10:51AM (#18664867)
My commits are the exact opposite of that comic. My initial commits are unfocused since it's the start of the project and there's a lot going on. As the project stabilizes and changes are smaller and on point, the commit messages become more focused as well.
Re:Write good git commit messages by BerislavLopac on Wednesday December 12, 2018 @10:57AM (#18664926)
I prefer to avoid "intermediary" WIP commits at all. Of course, I still make such commits to avoid losing my work, but I continuously amend the first commit rather then creating new ones (unless I'm experimenting, which goes to a separate branch anyway). Multiple commits usually lead to a rebase before merging, which tends to be more difficult than amending.