Hacker News new | past | comments | ask | show | jobs | submit login

wait there is another way?



I've used GitExtensions from the start of my Git usage. I've never had to blow any of my repos away at any point. I also use things like Rebase without thinking about it, something which from what I've read on here is considered a slightly unusual/difficult task.

Using GitExtensions means I can use Git as easily as any other tool, I never give it a second thought. I see the command line commands being executed, but never think about them. The flipside is I'd be knackered if I had to use the command line only.


I used GitExtension for years, but then I switched to Linux some years ago, so I had to find an alternative. I used SourceTree for a while, but I hated the UX. I tried GitKraken when it first came out, but it had a lot of issues that didn't make it appropriate for my workflow. After a couple more years, GitKraken had improved enough that I was able to switch to it. I've been using it for maybe 4 or 5 years now.


The pricing of GitKraken is a little frustrating. 5 pounds a month is quite a hefty price just to be able to use a private repo. Especially since it has not materially changed for my usage, so I would have been much happier giving them the £50 for a single licence.

This is once of those scenarios where subscription for an enterprise might be a thing, but makes no sense for me. The JetBrains model would make sense and I could justify that.


$5/m is honestly peanuts. The amount of value I get from it is way, way more than that. I pay it yearly, like I do for PHPStorm.


But if you get no value from PHPStorm you can stop paying for it and you do not lose access unlike a subscription.

You just don't get new features.

My issue is that I do not get £5 worth of value each month from GitKraken. I get value every couple of months, and it is to explain to other people what they are doing wrong rather than direct value for me.


Then stop paying for it.


Stop paying for what? I don't pay for GitKraken because I can't justify subscribing to software that doesn't materially change.

The risk is that they have to keep "doing stuff" to justify a subscription and we will end up with a new email client.


Hahahahahahaha


GitKraken is amazing, I'm a happy customer through work. makes me happy when electron apps aren't crap.


“Tower” is quite good. Highly recommended.


MacOS and Windows only


    git stash
    git reset --hard master
    git pull
    git stash pop


Uh oh, you've now merged remote master into your local master which was two commits ahead and 3 behind!

My git config has fast-forward only for pulls and I habitually use --ff-only for any pull :)


The command you want is "git pull --rebase". There are configuration settings to make "git pull" rebase by default, and I'd recommend always turning that on that default (which may be by why the person above omitted it from his pull command).

I actually thought "git pull" did "git pull --rebase" by default (this may be what you get from running `git --configure` without modifications?), but maybe I've just been configuring it that way. You can achieve this in your global Git configuration by setting "pull.rebase" to "true".

I don't think it's sane behavior for "git pull" to do anything else besides rebase the local change onto the upstream branch, so I'm surprised it's not the command's default behavior. Has the project not changed the CLI for compatibility reasons or something?

When do you ever want a "git pull" that's not a rebase? That generates a merge commit saying "Merge master into origin/master" (or something similar) which is stupid. If you really want to use actual branches for some reason, that's fine, but "merge master into master" commits are an anti-pattern that if I ever see in a Git repository I'm working on or responsible for, results in me having a conversation with the author about how to use Git correctly.


I actually don't want to rebase. Rebase can rewrite your local history and make it impossible for you to push without doing a force push (or some other more complicated manuevering). The only time pull with rebase is okay (on a shared branch such as master) is when you know that your local branch is strictly behind remote. That's exactly what --ff-only does. It rebases only if you are behind remote, and declines to do so if you are ahead so you can sort your shit out without rewriting history.


If "git pull --rebase" succeeds without reporting a merge conflict, then it's tantamount to having executed the command with "--ff-only".

I believe you are incorrect however. "git pulll --rebase" will not ever rewrite history from the origin repository. It will only ever modify your local unpublished commits to account for new commits from the origin branch. If your change and the new commits from origin aren't touching the same lines or files, then the update is seamless [1].

If there is a conflict because your change and a new commit from origin both changed the same line in the same file, this can result in a merge commit that you need to resolve. But you resolve this locally, by updating your (unpushed, local) commit(s) to account for the new history. When you complete the merge, it will not show up as a merge commit in the repository -- you will simply have simply amended your local unpublished commit(s) only to account for the changes in upstream, and you will have seen every conflict and resolved each one yourself. When the process is complete, and you've resolved the merge, you'll have a nice linear branch where your commit(s) are on the tip of the origin branch.

The flag "--ff-only" basically just means "refuse to start a local merge while performing this operation, and instead fail".

Because of the potential for these merge conflicts, it's a best practice to "git pull" frequently, so that if there are conflicts you can deal with them incrementally (and possibly discuss the software design with coworkers/project partners if the design is beginning to diverge -- and so people can coordinate what they're working on and try to stay out of each other's way), instead of working through a massive pile of conflicts at the end of your "local 'branch'" (i.e. the code in your personal Git repo that constitutes unpushed commits to the upstream branch).

Additionally, all of the central Git repositories I've worked in in a professional context were also configured to disallow "git push --force" (a command that can rewrite history), for all "real" branches. These systems gave users their own private Git repo sandbox (just like you can fork a repo on GitHub) where they can force push if they want to (but is backed up centrally like GitHub to avoid the loss of work). This personal repo was very useful for saving my work. I was in the habit of committing and pushing to the private repo about once every 30m-1h (to eliminate the chance of major work loss due to hardware failure). Almost always I'd squash all of these commits into one before rebasing onto master, so that the change comes in as a single commit, unless it would be too large to review.

In the occasional circumstances where I've legitimately needed to rewrite history for some reason -- say credentials got into the repository, or someone generated one of these "merge master into master" commits -- then I would change HEAD from master to another branch, delete master, and then recreate it with the desired state. (And even that operation would show up in the system's logs, so in the case of something like credentials you'd additionally contact the security or source control team to make sure the commit objects containing the credentials were actually deleted out of the repo history completely, including stuff you can find only via the reflog.) Then contact the team working on the repo to let them know that you had to rewrite history to correct a problem.

I would recommend disabling "git push --force" for all collaborative projects. If you're operating the repository, you can do this by invoking "git config --system receive" and setting "denyNonFastForwards true". In GitHub there's probably a repository setting switch somewhere.

Once professional software engineers start working with Git all day long, they quickly get past the beginner stage and the need to do this kind of stuff is very rare.

[1] It doesn't mean the software will work though, even if both changes would have worked in isolation. You still need to inspect and test the results of "git pull (--ff-only)", since even if there are no conflicts like commits that modify the same lines as yours, or there are conflicts that Git can resolve automatically, it's possible for the resultant software logic to be defective, since Git has no semantic understanding of the code.


> If "git pull --rebase" succeeds without reporting a merge conflict, then it's tantamount to having executed the command with "--ff-only".

this is not correct. git rebase, as with git merge, will automatically resolve conflicts using a 3-way merge algorithm.

> It will only ever modify your local

this is correct.

> unpublished commits

this is not correct. git rebase (in its default mode) rebases all commits that are not upstream onto the upstream. it has nothing to do with whether they are published or not. if you have a published feature branch, and git pull --rebase into it, git rebase will dutifully rebase all your commits.


> I was in the habit of committing and pushing to the private repo about once every 30m-1h (to eliminate the chance of major work loss due to hardware failure).

I get pushing every day, but how unreliable does your PC have to be if you feel you need to push every hour???

> (And even that operation would show up in the system's logs, so in the case of something like credentials you'd additionally contact the security or source control team to make sure the commit objects containing the credentials were actually deleted out of the repo history completely, including stuff you can find only via the reflog.)

You can't un-leak credentials. The only valid action for leaked credentials is to invalidate them, not to pretend that they were never leaked.


> how unreliable does your PC have to be if you feel you need to push every hour???

Hey, I commit and push on a branch on my fork of the repo every time my unit tests work and sometimes if they don't.

It's a single command, `gi`. My joke is "commit/push is the new save" though I'm not that bad...

No one but me has to see that branch. I rely on my rebasing skills and a library of git tools to produce a small number manicured commits out of it with no work.

It works so well. For one, if I am going from one machine to another, I can literally work and then step off my machine and continue on the other with a pull but no interruption.

At any time, I can just send someone a question with a permalink to the code as it was at that moment, and keep working while waiting for the answer.

I never have much uncommitted work in the current branch, so I can almost immediately start a new bugfix in an emergency.

> The only valid action for leaked credentials is to invalidate them,

Quoted for truth.


`git pull --rebase` usually is what I need to do. To save local changes and rebase to the git remote's branch:

  # git branch -av;
  # git remote -v;
  # git reflog; git help reflog; man git-reflog
  # git show HEAD@{0}
  # git log -n5 --graph;
  git add -A; git status;
  git stash; git stash list;
  git pull --rebase;
  #git pull --rebase origin develop
  # git fetch origin develop
  # git rebase origin/develop
  git stash pop;
  git stash list;
  git status;
  # git commit
  # git rebase -i HEAD~5 # squash
  # git push
HubFlow does branch merging correctly because I never can. Even when it's just me and I don't remember how I was handling tags of releases on which branch, I just reach for HubFlow now and it's pretty much good.

There's a way to default to --rebase for pulls: is there a reason not to set that in a global gitconfig? Edit: From https://stackoverflow.com/questions/13846300/how-to-make-git... :

> There are now 3 different levels of configuration for default pull behaviour. From most general to most fine grained they are: […]

  git config --global pull.rebase true


> "git pulll --rebase" will not ever rewrite history from the origin repository. It will only ever modify your local unpublished commits to account for new commits from the origin branch.

After reading more about it, you are right about that. It will only apply your commits to the tip of remote.


as far as i can tell there's no git --configure. you may be confusing it with Xorg -configure, which is (very) obsolete and shouldn't be used.


Yeah. "git pull" is so bad. I wish it didn't exist. Every single time a coworker has gotten into a stuck state is because they used "git pull" which made a merge commit when there shouldn't have been one. It's mostly stopped happening since I yelled at everyone to _please_ configure their machine with ff-only.


Invest in (or build?) an enterprise content management system for people that don't, for whatever reason, think of SCM in terms of commits, branches, and graphs.

If you can make one that thinks in terms of git on the backend, great.

If you want to go a bit further, you could expose the underlying operations to the user. You will need to get them to reason around and interact with the minimal requirements inherent to a versioning system, namely explicit versioning and an explicit commit process, along with explicit merging and conflict resolution.

There are GUI clients that help with some of this, but you're not going to get away from some concept of dealing with branches and merges in any SCM. You hear about it less often, but you'd have the same troubles dealing with a chewed up repository in Perforce, ClearCase, or the like.

(edit: even Subversion!)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: