3
3
#include "lockfile.h"
4
4
#include "commit.h"
5
5
#include "tag.h"
6
+ #include "blob.h"
6
7
#include "refs.h"
7
8
#include "builtin.h"
8
9
#include "exec_cmd.h"
12
13
#include "hashmap.h"
13
14
#include "argv-array.h"
14
15
#include "run-command.h"
16
+ #include "revision.h"
17
+ #include "list-objects.h"
15
18
16
19
#define MAX_TAGS (FLAG_BITS - 1)
17
20
@@ -256,7 +259,7 @@ static unsigned long finish_depth_computation(
256
259
return seen_commits ;
257
260
}
258
261
259
- static void display_name (struct commit_name * n )
262
+ static void append_name (struct commit_name * n , struct strbuf * dst )
260
263
{
261
264
if (n -> prio == 2 && !n -> tag ) {
262
265
n -> tag = lookup_tag (& n -> oid );
@@ -272,19 +275,18 @@ static void display_name(struct commit_name *n)
272
275
}
273
276
274
277
if (n -> tag )
275
- printf ( "%s" , n -> tag -> tag );
278
+ strbuf_addstr ( dst , n -> tag -> tag );
276
279
else
277
- printf ( "%s" , n -> path );
280
+ strbuf_addstr ( dst , n -> path );
278
281
}
279
282
280
- static void show_suffix (int depth , const struct object_id * oid )
283
+ static void append_suffix (int depth , const struct object_id * oid , struct strbuf * dst )
281
284
{
282
- printf ( "-%d-g%s" , depth , find_unique_abbrev (oid -> hash , abbrev ));
285
+ strbuf_addf ( dst , "-%d-g%s" , depth , find_unique_abbrev (oid -> hash , abbrev ));
283
286
}
284
287
285
- static void describe ( const char * arg , int last_one )
288
+ static void describe_commit ( struct object_id * oid , struct strbuf * dst )
286
289
{
287
- struct object_id oid ;
288
290
struct commit * cmit , * gave_up_on = NULL ;
289
291
struct commit_list * list ;
290
292
struct commit_name * n ;
@@ -293,30 +295,25 @@ static void describe(const char *arg, int last_one)
293
295
unsigned long seen_commits = 0 ;
294
296
unsigned int unannotated_cnt = 0 ;
295
297
296
- if (get_oid (arg , & oid ))
297
- die (_ ("Not a valid object name %s" ), arg );
298
- cmit = lookup_commit_reference (& oid );
299
- if (!cmit )
300
- die (_ ("%s is not a valid '%s' object" ), arg , commit_type );
298
+ cmit = lookup_commit_reference (oid );
301
299
302
300
n = find_commit_name (& cmit -> object .oid );
303
301
if (n && (tags || all || n -> prio == 2 )) {
304
302
/*
305
303
* Exact match to an existing ref.
306
304
*/
307
- display_name ( n );
305
+ append_name ( n , dst );
308
306
if (longformat )
309
- show_suffix (0 , n -> tag ? & n -> tag -> tagged -> oid : & oid );
307
+ append_suffix (0 , n -> tag ? & n -> tag -> tagged -> oid : oid , dst );
310
308
if (suffix )
311
- printf ("%s" , suffix );
312
- printf ("\n" );
309
+ strbuf_addstr (dst , suffix );
313
310
return ;
314
311
}
315
312
316
313
if (!max_candidates )
317
314
die (_ ("no tag exactly matches '%s'" ), oid_to_hex (& cmit -> object .oid ));
318
315
if (debug )
319
- fprintf (stderr , _ ("searching to describe %s \n" ), arg );
316
+ fprintf (stderr , _ ("No exact match on refs or tags, searching to describe\n" ));
320
317
321
318
if (!have_util ) {
322
319
struct hashmap_iter iter ;
@@ -381,22 +378,21 @@ static void describe(const char *arg, int last_one)
381
378
}
382
379
383
380
if (!match_cnt ) {
384
- struct object_id * oid = & cmit -> object .oid ;
381
+ struct object_id * cmit_oid = & cmit -> object .oid ;
385
382
if (always ) {
386
- printf ( "%s" , find_unique_abbrev (oid -> hash , abbrev ));
383
+ strbuf_addstr ( dst , find_unique_abbrev (cmit_oid -> hash , abbrev ));
387
384
if (suffix )
388
- printf ("%s" , suffix );
389
- printf ("\n" );
385
+ strbuf_addstr (dst , suffix );
390
386
return ;
391
387
}
392
388
if (unannotated_cnt )
393
389
die (_ ("No annotated tags can describe '%s'.\n"
394
390
"However, there were unannotated tags: try --tags." ),
395
- oid_to_hex (oid ));
391
+ oid_to_hex (cmit_oid ));
396
392
else
397
393
die (_ ("No tags can describe '%s'.\n"
398
394
"Try --always, or create some tags." ),
399
- oid_to_hex (oid ));
395
+ oid_to_hex (cmit_oid ));
400
396
}
401
397
402
398
QSORT (all_matches , match_cnt , compare_pt );
@@ -434,15 +430,89 @@ static void describe(const char *arg, int last_one)
434
430
}
435
431
}
436
432
437
- display_name (all_matches [0 ].name );
433
+ append_name (all_matches [0 ].name , dst );
438
434
if (abbrev )
439
- show_suffix (all_matches [0 ].depth , & cmit -> object .oid );
435
+ append_suffix (all_matches [0 ].depth , & cmit -> object .oid , dst );
440
436
if (suffix )
441
- printf ("%s" , suffix );
442
- printf ("\n" );
437
+ strbuf_addstr (dst , suffix );
438
+ }
439
+
440
+ struct process_commit_data {
441
+ struct object_id current_commit ;
442
+ struct object_id looking_for ;
443
+ struct strbuf * dst ;
444
+ struct rev_info * revs ;
445
+ };
446
+
447
+ static void process_commit (struct commit * commit , void * data )
448
+ {
449
+ struct process_commit_data * pcd = data ;
450
+ pcd -> current_commit = commit -> object .oid ;
451
+ }
452
+
453
+ static void process_object (struct object * obj , const char * path , void * data )
454
+ {
455
+ struct process_commit_data * pcd = data ;
456
+
457
+ if (!oidcmp (& pcd -> looking_for , & obj -> oid ) && !pcd -> dst -> len ) {
458
+ reset_revision_walk ();
459
+ describe_commit (& pcd -> current_commit , pcd -> dst );
460
+ strbuf_addf (pcd -> dst , ":%s" , path );
461
+ pcd -> revs -> max_count = 0 ;
462
+ }
463
+ }
464
+
465
+ static void describe_blob (struct object_id oid , struct strbuf * dst )
466
+ {
467
+ struct rev_info revs ;
468
+ struct argv_array args = ARGV_ARRAY_INIT ;
469
+ struct process_commit_data pcd = { null_oid , oid , dst , & revs };
470
+
471
+ argv_array_pushl (& args , "internal: The first arg is not parsed" ,
472
+ "--all" , "--reflog" , /* as many starting points as possible */
473
+ /* NEEDSWORK: --all is incompatible with worktrees for now: */
474
+ "--single-worktree" ,
475
+ "--objects" ,
476
+ "--in-commit-order" ,
477
+ NULL );
478
+
479
+ init_revisions (& revs , NULL );
480
+ if (setup_revisions (args .argc , args .argv , & revs , NULL ) > 1 )
481
+ BUG ("setup_revisions could not handle all args?" );
482
+
483
+ if (prepare_revision_walk (& revs ))
484
+ die ("revision walk setup failed" );
485
+
486
+ traverse_commit_list (& revs , process_commit , process_object , & pcd );
487
+ reset_revision_walk ();
488
+ }
489
+
490
+ static void describe (const char * arg , int last_one )
491
+ {
492
+ struct object_id oid ;
493
+ struct commit * cmit ;
494
+ struct strbuf sb = STRBUF_INIT ;
495
+
496
+ if (debug )
497
+ fprintf (stderr , _ ("describe %s\n" ), arg );
498
+
499
+ if (get_oid (arg , & oid ))
500
+ die (_ ("Not a valid object name %s" ), arg );
501
+ cmit = lookup_commit_reference_gently (& oid , 1 );
502
+
503
+ if (cmit )
504
+ describe_commit (& oid , & sb );
505
+ else if (lookup_blob (& oid ))
506
+ describe_blob (oid , & sb );
507
+ else
508
+ die (_ ("%s is neither a commit nor blob" ), arg );
509
+
510
+ puts (sb .buf );
443
511
444
512
if (!last_one )
445
513
clear_commit_marks (cmit , -1 );
514
+
515
+ strbuf_release (& sb );
446
516
}
447
517
448
518
int cmd_describe (int argc , const char * * argv , const char * prefix )
0 commit comments