Esta é uma generalização da minha pergunta anterior , com o objetivo de melhorar meu entendimento sobre o que pode e o que não pode ser feito internamente no Git.
Suponha que eu tenha um commit A, e eu queira alterar alguns metadados arbitrários, sejam os pais, a árvore, o autor/committer, o autor/data do commit, a mensagem do commit ou a assinatura gpg, para produzir um novo commit B que compartilhe todos os metadados com A, exceto os bits que eu alterei. Além disso, suponha que minhas alterações não exijam a criação de uma nova árvore; estou usando a árvore original ou substituindo outra árvore existente.
Atualmente, estou ciente de pelo menos duas maneiras de fazer isso:
- Posso
git checkout A
e então usargit commit --amend
com várias opções. Isso é nativo do git e moderadamente flexível em termos do que pode ser alterado. No entanto, é interativo e toca a árvore de trabalho. - Posso usar
git cat-file | <insert_sed_script> | git hash-object -w -t commit --stdin
como descreve esta resposta à minha pergunta anterior.
A segunda maneira é semanticamente o que estou procurando, mas requer um script externo que execute manipulação de texto na representação de texto de um commit.
A manipulação de texto é a única opção atual para transformar objetos de confirmação de forma não interativa ou existe uma maneira mais estruturada e semântica de manipular os metadados de confirmação?
- Exemplo 1: Em vez de escrever um script sed que semanticamente diz "exclua as linhas que começam com
parent
e então insira novas linhas que começam com pai", posso escrever um comando git que diz "defina os pais deste commit como X, Y, Z" e gerar o commit com essa alteração? (o git replace pode lidar com esse caso, mas não com o caso geral.) - Exemplo 2: Em vez de escrever um script sed que identifica a mensagem de confirmação com base em expressões regulares e a substitui, posso escrever um comando git que diz "defina a mensagem de confirmação desta confirmação como 'hello world'" e gerar a confirmação com essa alteração?
Parte da motivação para perguntar isso é curiosidade intelectual; a outra parte é que estou pensando em criar essas ferramentas externamente (envolvendo a manipulação de texto), caso elas ainda não existam.
git commit-tree
cria objetos de commit de uma árvore. A mensagem de commit pode ser fornecida via stdin ou-m
option.-S
/--gpg-sign
permite assinar o novo objeto de commit. DefinaGIT_AUTHOR_DATE
eGIT_COMMITTER_DATE
para especificar o tempo do autor e do committer, respectivamente.Exemplo:
Para reutilizar/modificar a mensagem de um commit existente, alimente-o via stdin:
Por exemplo, para acrescentar "Feliz Natal!" à mensagem do seu commit:
Se você precisar copiar a data/nome/e-mail do autor/committador do commit original, preencha as variáveis de ambiente com as informações obtidas do commit original: