January 08, 2013
On 1/6/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> What I'd want to do next is define the alias such that other participants to the dlang project may use it. With time we'd collect a good set of macros that help our process.

This is what I use locally in my .bashrc:

# win32 helpers
alias cd..='cd ..'
alias dir="ls -F"
alias cls='clear'
alias c:='cd /c/'
alias d:='cd /d/'
alias e:='cd /e/'
alias f:='cd /f/'
alias g:='cd /g/'

# git stuff
alias com='git checkout master'
alias fpush='git push -f' # needed after a local rebase
alias hreset='git reset --hard head' # reset to the last commit,
discarding all changes
alias hdiff='git diff head~1' # check what I've added with the latest commit
alias amend='git commit --amend' # edit the last commit message
alias rb='git pull --rebase upstream master' # rebase local branch and
verify there's no merge conflicts
alias co='git checkout'
alias diff='git diff' # what did I change so far without staging/commiting?
alias cdiff='git diff --cached' # what am I about to commit?
alias add='git add'
alias gcm='git commit -m' # quick commit with message
alias gcn='git checkout -b' #quick create a new branch

I only add stuff there when I realize I'm constantly retyping some long command. I should probably add 'git rebase -i head~' too.
January 08, 2013
On Tuesday, 8 January 2013 at 01:54:43 UTC, Andrei Alexandrescu wrote:
> On 1/6/13 3:41 PM, Jonathan M Davis wrote:
>> I'm arguing that people should actually learn how to use git properly rather
>> than creating crutches for themselves.
>
> False choice.

Yet one should come before the other.

>> The more you try and do with git
>> without learning it properly, the more problems you're likely to run into
>> (e.g. by running commands that you don't entirely understand and ending up
>> with nasty side effects). So, I think that it's just plain bad practice to
>> create such macros.
>
> I know how the shell works quite well but that doesn't stop me from writing scripts and aliases.
>
> This boils down to advocating one needs to type by hand sequences of commands instead of defining higher-level scripts that have a cohesive meaning.

Such as?

Points:
1. If everyone needed to type the same sequences of commands all the time, git by itself would be a rather poor tool.
2. Automating commands that destroy (or move in a hard-to-reach place) user data has obvious consequences.
3. Your workflow may be different from the typical user's. I agree that untypical usage (e.g. a project maintainer's) might benefit from some automation.
4. Your workflow might be suboptimal (due to incomplete knowledge of git).

Enumerate some actions that you have to resort to typing series of commands to perform, and let's examine solutions. I'll reply to your original problem with a better solution, as well.
January 08, 2013
On Sunday, 6 January 2013 at 19:50:47 UTC, Andrei Alexandrescu wrote:
> For example, I tried today to get the latest and greatest phobos into my repo, and got a bunch of conflicts. I searched a while on the net to figure what the command for "just get the latest remote into my local copy", which is entirely possible but not obvious and not easy to find.

#!/bin/bash

# Add untracked files to the index, so they're stashed and deleted.
# This gives us a cleaner directory, and avoids possible collisions with files that are currently untracked, but are tracked in master.
git add --all .

# Saves any changes in the working tree or index, if any, as a stash.
git stash save "Automatic save before switching to latest master"

# Now that the working tree is clean, switch to whatever the "master" branch is currently.
git checkout master

# Reset the master branch to point to the remote's tracking branch.
# This allows the merge implied by "git pull" to be a fast-forward.
git reset --hard origin/master

# Download new objects, update tracking branch, fast-forward current branch to tracking branch.
git pull

# End

This script assumes that the branch you want is "master", and that the remote is called "origin".

Do not invoke the script directly. Rather, create an alias in your .gitconfig which launches the script. This will allow it to work correctly even from a subdirectory in the project.

Instructions to recover data from accidental usage of this script:

To find what branch (or commit, with detached HEAD) you were on before the switch to master, check the output of `git reflog HEAD`. It should look something like this:

eb5121f HEAD@{0}: pull: Fast-forward
8e7ed2b HEAD@{1}: reset: moving to origin/master
d49acd5 HEAD@{2}: checkout: moving from foo to master
ecdc09c HEAD@{3}: ...
...

The commit you were on should be below the line the description of which starts with "checkout:".

Uncommitted data in your index or working tree will be in the git stash. Use `git stash apply` to apply the patch to the current working tree.

The script could be improved to be a little more efficient (e.g. avoid checking out the old master), or less noisy or reliant on the environment (e.g. detecting the name of the remote).
January 08, 2013
On 1/7/13 10:56 PM, Vladimir Panteleev wrote:
> On Sunday, 6 January 2013 at 19:50:47 UTC, Andrei Alexandrescu wrote:
>> For example, I tried today to get the latest and greatest phobos into
>> my repo, and got a bunch of conflicts. I searched a while on the net
>> to figure what the command for "just get the latest remote into my
>> local copy", which is entirely possible but not obvious and not easy
>> to find.
>
> #!/bin/bash
[snip]

This script is bad because it does not do any meaningful error handling and offers no good explanation on how to proceed if either step fails. If you thought I had this kind of style in mind, I agree that using such scripts is a terrible idea.

Andrei

January 08, 2013
On Tuesday, 8 January 2013 at 07:07:18 UTC, Andrei Alexandrescu wrote:
> This script is bad because it does not do any meaningful error handling and offers no good explanation on how to proceed if either step fails.

Indeed - I wanted to avoid using any syntax / commands that someone wouldn't use in daily git use.

> If you thought I had this kind of style in mind, I agree that using such scripts is a terrible idea.

However, I can't think of any scenario where a command would fail half-way through the script and lead to undesirable consequences, assuming the git repository is not corrupted. The recovery instructions would still apply.

Therefore, just add "set -e" at the top for the peace of mind.
January 08, 2013
On Monday, January 07, 2013 17:54:40 Andrei Alexandrescu wrote:
> I know how the shell works quite well but that doesn't stop me from writing scripts and aliases.
> 
> This boils down to advocating one needs to type by hand sequences of commands instead of defining higher-level scripts that have a cohesive meaning.

If you want to create scripts or aliases for yourself, fine. And other people can do the same for whatever they need. But I think that any specific example of a git alias for D's repos needs to be examined in detail and have very strong arguments for its inclusion.

In my experience, the commands needed to operate on our repos are not complicated but rather are very basic git commands that anyone using git on a regular basis should know. And the command that you provided as an example that you thought needed an alias is a command that no one should even be using normally. I think that we need actual, solid examples if we're really going to discuss adding any aliases or scripts, and the example that you provided is a bad one.

- Jonathan M Davis
January 09, 2013
On 01/06/2013 02:50 PM, Andrei Alexandrescu wrote:
> Sent this to dmd-internals, opening for a broader discussion:
>
> Hello,
>
>
> I wonder how we can define a few aliases of project-wide usefulness to
> git. For example, I tried today to get the latest and greatest phobos
> into my repo, and got a bunch of conflicts. I searched a while on the
> net to figure what the command for "just get the latest remote into my
> local copy", which is entirely possible but not obvious and not easy to
> find.

If you use local branches instead of working directly on master then getting the latest and greatest is as simple as

  git checkout master
  git pull

Then you can do

  git checkout mybranch
  git rebase master

to get new upstream changes into your local branch(es). You might sometimes need to use more complicated versions of the rebase command, but no matter how wacky things get with merge conflicts, it will only be affecting your local branch. (I often do "git checkout mybranch; git checkout -b newmybranch; git rebase master", if I'm worried about conflicts; this way I have a new branch to play around with fixing conflicts in, and it's easy to just scrap it and switch back to known-good versions of master and local branches).

tl;dr: more local branches means less need for arcane git options.

--Ed
January 10, 2013
> tl;dr: more local branches means less need for arcane git options.
>
> --Ed

AFAIR you can resist the temptation to have a local master branch at all and just run "git pull --rebase upstream/master" where upstream is configured to be original D repo.
January 10, 2013
On 01/10/2013 04:20 AM, mist wrote:
>> tl;dr: more local branches means less need for arcane git options.
>>
>> --Ed
>
> AFAIR you can resist the temptation to have a local master branch at all
> and just run "git pull --rebase upstream/master" where upstream is
> configured to be original D repo.

And then you're right back where we started; Andrei's original problem was how to just get a local copy of the latest and greatest upstream without having merge conflicts, which (if you don't have a separate local master) means using "git pull --rebase -s recursive -X ours".

But: "rebase -X ours" does not throw away all of your changes; it keeps the ones that can be cleanly merged. So what you end up with is "the latest and greatest plus SOME of my local changes", which might not be what you wanted.

(Also, git branches are not temptations to be resisted.)

--Ed
January 11, 2013
>
> And then you're right back where we started; Andrei's original problem was how to just get a local copy of the latest and greatest upstream without having merge conflicts, which (if you don't have a separate local master) means using "git pull --rebase -s recursive -X ours".
>
> But: "rebase -X ours" does not throw away all of your changes; it keeps the ones that can be cleanly merged. So what you end up with is "the latest and greatest plus SOME of my local changes", which might not be what you wanted.
>
> (Also, git branches are not temptations to be resisted.)
>
> --Ed

"temptation to be resisted" is working on master branch instead of feature/bug branch, not git branches ;) Well, if you want to have a look at current upstream without merging - why not just checkout it in another temporary branch? I do not propose to get rid of master at all, just made an observation that it is easy to make small fix directly on master when it is hanging around so close.